this post was submitted on 03 Jul 2025
577 points (100.0% liked)

Selfhosted

46677 readers
1043 users here now

A place to share alternatives to popular online services that can be self-hosted without giving up privacy or locking you into a service you don't control.

Rules:

  1. Be civil: we're here to support and learn from one another. Insults won't be tolerated. Flame wars are frowned upon.

  2. No spam posting.

  3. Posts have to be centered around self-hosting. There are other communities for discussing hardware or home computing. If it's not obvious why your post topic revolves around selfhosting, please include details to make it clear.

  4. Don't duplicate the full text of your blog or github here. Just post the link for folks to click.

  5. Submission headline should match the article title (don’t cherry-pick information from the title to fit your agenda).

  6. No trolling.

Resources:

Any issues on the community? Report it using the report flag.

Questions? DM the mods!

founded 2 years ago
MODERATORS
 

Hey everyone!

I'm excited to introduce Reitti, a location tracking and analysis application designed to help you gain insights about your movement patterns and significant places—all while keeping your data private on your own server.

Core Capabilities:

  • Visit Tracking: Automatically recognizes and categorizes the places where you spend time, using customizable detection algorithms
  • Trip Analysis: Analyzes your movements between locations to understand how you travel whether by walking, cycling, or driving
  • Interactive Timeline: Visualizes all your past activities on an interactive timeline with map and list views that show visit duration, transport method, and distance traveled

Photo Integration:

  • Connect your self-hosted Immich photo server to seamlessly display photos taken at specific locations right within Reitti's timeline. The interactive photo viewer lets you browse galleries for each place.

Data Import Options:

  • Multiple Formats Supported: Reitti can import existing location data from GPX, GeoJSON, and Google Takeout (JSON) backups
  • (Near) Real-time Updates: Automatically receive location info via mobile apps like OwnTracks, GPSLogger or our REST API

Customization:

  • Multi-geocoding Services: Configurable options to convert coordinates to human-readable addresses using providers like Nominatim
  • User Profiles: Customize individual display names, password management, and API token security under your own control

Self-hosting:

  • Reitti is designed to be deployed on your own infrastructure using Docker containers. We provide configuration templates to set up linked services like PostgreSQL, RabbitMQ and Redis that keep all your location data private.

Reitti is still early in development but has already developed extensive capabilities. I'd love to hear your feedback and answer any questions to tailor Reitti to meet the community's needs.

Hope this sparks some interest!

Daniel

top 50 comments
sorted by: hot top controversial new old
[–] [email protected] 2 points 13 hours ago (1 children)

Got it up and running, looks neat!

Is there a way to import old pictures from Immich? If I take new ones they do show up on Reitti, but none of the old ones are shown.

[–] [email protected] 3 points 12 hours ago (1 children)

Thank you for testing Reitti. 🙏

It depends on two key requirements for Reitti:

  1. First, it finds all photos from Immich taken on the day you selected.
  2. Then, it filters these photos based on the selected map bounds, using the embedded EXIF geolocation data (where the photo was shot).

If the EXIF data does not contain geolocation information, we currently cannot display those photos because their placement on the map cannot be determined.

Could you please verify in Immich if the expected photo has its location in the metadata? If it is available there, then the issue might lie in how Reitti is parsing that specific data.

[–] [email protected] 3 points 11 hours ago (1 children)

Thanks for the explanation! Seems to work correctly after all, pictures do show up when I change the date on timeline instead of just staring at current date, 👍 Had just not understood how to use Reitti properly.

[–] [email protected] 3 points 11 hours ago

Glad I could help :)

[–] [email protected] 8 points 19 hours ago (1 children)

I managed to break our instance. I imported several years worth of google takeout location data, and now the "stay-detection-queue" is stalled.

[–] [email protected] 6 points 18 hours ago (1 children)

Congratulations 😆

To help with that I would need some information:

  • does it show anything in the logs?
  • what do you mean by several years or how big was the Records.json?

Thank you for testing 🙂

[–] [email protected] 4 points 17 hours ago (1 children)

It's a 1gig json file that has about 10 years of data. I get multiple repeats of the rabbit timeout in the logs. The Job Status section tells me that it's got just under 9 hours of processing remaining for just over 16,000 in the stay-detection-queue. The numbers change slightly, so something is happening, but it's been going for over 12 hours now, and the time remaining is slowly going up, not down.

***
[ntContainer#2-1] c.d.r.s.p.VisitDetectionService          : Detected 61806 stay points for user ada
reitti-1  | 2025-07-04T03:06:17.848Z  WARN 1
***
[ntContainer#2-1] o.s.a.r.l.SimpleMessageListenerContainer : Consumer raised exception, processing can restart if the connection factory supports it
reitti-1  |
reitti-1  | com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - delivery acknowledgement on channel 9 timed out. Timeout value used: 1800000 ms. This timeout value can be configured, see consumers doc guide to learn more, class-id=0, method-id=0)
reitti-1  |     at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.checkShutdown(BlockingQueueConsumer.java:493) ~[spring-rabbit-3.2.5.jar!/:3.2.5]
reitti-1  |     at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.nextMessage(BlockingQueueConsumer.java:554) ~[spring-rabbit-3.2.5.jar!/:3.2.5]
reitti-1  |     at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1046) ~[spring-rabbit-3.2.5.jar!/:3.2.5]
reitti-1  |     at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1021) ~[spring-rabbit-3.2.5.jar!/:3.2.5]
reitti-1  |     at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1423) ~[spring-rabbit-3.2.5.jar!/:3.2.5]
reitti-1  |     at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1324) ~[spring-rabbit-3.2.5.jar!/:3.2.5]
reitti-1  |     at java.base/java.lang.Thread.run(Unknown Source) ~[na:na]
reitti-1  | Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - delivery acknowledgement on channel 9 timed out. Timeout value used: 1800000 ms. This timeout value can be configured, see consumers doc guide to learn more, class-id=0, method-id=0)
reitti-1  |     at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:528) ~[amqp-client-5.25.0.jar!/:5.25.0]
reitti-1  |     at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:349) ~[amqp-client-5.25.0.jar!/:5.25.0]
reitti-1  |     at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:193) ~[amqp-client-5.25.0.jar!/:5.25.0]
reitti-1  |     at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:125) ~[amqp-client-5.25.0.jar!/:5.25.0]
reitti-1  |     at com.rabbitmq.client.impl.AMQConnection.readFrame(AMQConnection.java:761) ~[amqp-client-5.25.0.jar!/:5.25.0]
reitti-1  |     at com.rabbitmq.client.impl.AMQConnection.access$400(AMQConnection.java:48) ~[amqp-client-5.25.0.jar!/:5.25.0]
reitti-1  |     at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:688) ~[amqp-client-5.25.0.jar!/:5.25.0]
reitti-1  |     ... 1 common frames omitted
[–] [email protected] 2 points 17 hours ago (1 children)

Thanks for the information. I will try to recreate it locally. In my testing I used a 600MB file and this took maybe 2 hours to process on my server. It is one of these ryzen 7 5825U. Since Reitti tries to do these analysis on multiple cores we start it with 4 to 16 Threads when processing. But the stay detection breaks when doing it that way, so it is locking per user to handle that. If now one of them takes a long time the others will break eventually. They will get resheduled 3 times until rabbitmq gives up.

On what type of system do you run it?

I will add some switches so it is configurable how many threads are opened and add some log statements to print out the duration it took for a single step.

[–] [email protected] 2 points 17 hours ago (1 children)
[–] [email protected] 2 points 16 hours ago* (last edited 16 hours ago) (1 children)

Hmm, I had hoped you say something like a Raspberry PI :D

But this should be enough to have it processed in a reasonable time. What I do not understand in the moment is, that the filesize should not affect it in any way. When importing it 100 Geopoints are bundled, send to RabbitMQ. From there we retrieve them, do some filtering and save them in the database. Then actually nothing happens anymore until the next processing run is triggered.

But this than works with the PostGis DB and not with the file anymore. So the culprit should be there somewhere. I will try to insert some fake data into mine and see how long it takes if i double my location points.

[–] [email protected] 1 points 16 hours ago (1 children)

I was also trying to set up GPSLogger whilst it was crunching through the backlog, and I manually transferred a file from that app before I had autologging configured. Not sure if that could have done it?

The times don't overlap, as the takeout file is only up until 2023

[–] [email protected] 1 points 16 hours ago* (last edited 16 hours ago) (1 children)

Thanks for getting back to me. I can look into it. I don't think it's connected, but you never know.

The data goes the same way, first to RabbitMQ and then the database. So it shouldn't matter, it's just another message or a bunch of them in the queue.

[–] [email protected] 1 points 14 hours ago (1 children)

Ok, so it may not be frozen. The numbers in the queue seem to imply it is, however, timelines and places are slowly filling out in my history. A couple of dates I had looked at previously were showing me tracklogs for the day, but not timeline information, and now, they're showing timelines for the day

[–] [email protected] 1 points 13 hours ago (1 children)

That's good, but I still question why it is so slow. If you receive these timeout exceptions more often, at some point the data will cease to be analyzed.

I just re-tested it with multiple concurrent imports into a clean DB, and the stay-detection-queue completed in 10 minutes. It's not normal for it to take that long for you. The component that should take the most time is actually the merge-visit-queue because this creates a lot of stress for the DB. This test was conducted on my laptop, equipped with an AMD Ryzen™ 7 PRO 8840U and 32GB of RAM.

[–] [email protected] 1 points 13 hours ago (1 children)

Since I last commented, the queue has jumped from about 9000 outstanding items, to 15,000 outstanding items, and it appears that I have timelines for a large amount of my history now.

However, the estimated time is still slowly creeping up (though only by a minute or two, despite adding 6000 more items to the queue).

I haven't uploaded anything manually that might have triggered the change in queue size.

Is there any external calls made during processing this queue that might be adding latency?

tl;dr - something is definitely happening

[–] [email protected] 1 points 12 hours ago

This process is not triggered by any external events.

Every ten minutes, an internal background job activates. Its function is to scan the database for any RawLocationPoints that haven't been processed yet. These unprocessed points are then batched into groups of 100, and each batch is sent as a message to be consumed by the stay-detection-queue. This process naturally adds to the workload of that queue.

However, if no new location data is being ingested, once all RawLocationPoints have been processed and their respective flags set, the stay-detection-queue should eventually clear, and the system should return to a idle state. I'm still puzzled as to why this initial queue (stay-detection-queue) is exhibiting such slow performance for you, as it's typically one of the faster steps.

[–] [email protected] 4 points 17 hours ago (1 children)

Hell yes! I turned off location data for immich but now I can use this!

[–] [email protected] 2 points 16 hours ago

It is actually awesome if you have some old photos with the geodata attached and scim through Reitti and suddenly one of them shows up :)

[–] [email protected] 46 points 1 day ago (2 children)

Fuck yeah this is awesome! The detail of Immich integration is just the icing on top of an awesome cake!

How demanding is it on server resources? Am I likely to be able to run it on an old Raspberry Pi that's also running a couple of other relatively light tasks? How much storage does it end up using over time? I'm probably going to try and get it running either on my Pi or my Synology NAS, though the latter has had issues with Docker containers in the past depending on the container's dependencies...

[–] [email protected] 16 points 1 day ago (9 children)

I have no clue if a raspberry will handle it. There a a couple of services involved to make it fast, but they are then another burden like RabbitMQ. Which make ingesting data instantaneous but you need extra processing power to handle the queues. It all comes with a tradeoff.

For size, there is mainly the PostGIS DB. I just checked and my db is around 800 MB for roughtly 8 1/2 Years of data.

Photon (the reverse geocode enabled in the compose file) is another beast. For Germany it takes 14 GB of storage while running, if you let PARALLELL updates enabled you can double that every time the index is updated. But you can remove that from the compose file and rely on external Geocoders. It is described in https://github.com/dedicatedcode/reitti?tab=readme-ov-file#reverse-geocoding-options

load more comments (9 replies)
load more comments (1 replies)
[–] [email protected] 2 points 21 hours ago (1 children)

I am slightly bothered by how the logo is quite off-center, is it intentional?

[–] [email protected] 7 points 18 hours ago

It was not intentional but after bothering not about it because i had other things on my mind i got used to it and now like it the way it is.

But for everyone who is bothered by that. If Reitti reaches 1k stars on Github I will add a switch to use a centered one 😊

[–] [email protected] 14 points 1 day ago (5 children)

This looks amazing, congratulations and thank you for making it FOSS. I was wondering if you are considering integrating with Home Assistant.

load more comments (5 replies)
[–] [email protected] 19 points 1 day ago (1 children)

My only concern is battery usage. Google has the advantage of OS integration, which skims location data for timeline history even when another app accesses location, which uses essentially no battery (since you would've been using location for that other app anyway).

But it's awesome that a tool like this exists anyways, great work.

[–] [email protected] 10 points 1 day ago (1 children)

Thank you :)

I understand your concerns, this is something every additional app would have to deal with.

For me it is ok to have GPSLogger running all the time, I think for what it is doing it is quite easy on the battery but I do not use my phone actively that much and I am happy if it survives a day which it does.

[–] [email protected] 4 points 1 day ago

I log my position every 5 seconds for years and gpslogger is not among any of the battery consuming processes if you use the device. If you don't use the phone at all, it will consume more power but that's no reason not to use it.

[–] [email protected] 6 points 1 day ago

Visually this is gorgeous

Really nice work!

[–] [email protected] 5 points 1 day ago (1 children)

That looks very neat. Thanks for starting this!

I guess this will directly compete with dawarich, right?

https://github.com/Freika/dawarich

[–] [email protected] 7 points 1 day ago (1 children)

I would not say compete. They are different in how things are done from my point of view. I want to focus more on the visits we have done in the past to relive some lost memories whereas Dwarich looks more "technical" for me. I have no better words for it, I hope you get my point in what i am trying to achieve with Reitti. So there should be enough room for both 🙂

I also do not have any intentions to offer a hosted version in the foreseeable future or even anytime.

[–] [email protected] 3 points 1 day ago* (last edited 1 day ago)

I get what you mean. The focus is different of dawarich. I'm really looking forward into checking reitti out!

[–] [email protected] 5 points 1 day ago (1 children)

Very very cool! I see that you can import GPX files: can you also do the opposite, i.e., export a GPX file for a selected time range?

[–] [email protected] 4 points 1 day ago (1 children)

I was thinking about that, but the main problem is that we do not store all the data which comes in.

If we ingest data from an app, I am pretty sure that the quality of the data is actually usable. But for example if we import an Records.json from Google Takeout. The quality of the earlier years is somewhat sketchy. For this we filter out some points like travelling with over 2000 km/h, sudden direction changes etc and they are lost forever. At least for Reitti they are unknown.

The feature would need a lot of explanation why the data we export is not the same we import.That is the reason I did not implemented it even if it would come in handy for testing stuff. Handling GPX files is a pita ...

[–] [email protected] 1 points 1 day ago

I understand. Currently, I'm using the NextCloud's extension Phonetrack, and one on my main use cases is to export GPX files to use them in Darktable and add geotracking information to the pictures I shoot with my camera. It works well, actually, but Phonetrack is not too intuitive and does not offer many other features: that's why I was looking with interest at this alternative!

[–] [email protected] 13 points 1 day ago (5 children)

This looks amazing, and I will try it out once it has reasonable NixOS support.

I especially like the immich integration.

Does it increase battery consumption of the phone a lot?

[–] [email protected] 12 points 1 day ago

Reitti on its own does not run on your phone. It relies on external apps to track your GPS location like GPSLogger or Owntracks. They will increase the battery consumption but I think it is bearable. I personally have setup GPSLogger to fetch every 30 seconds a GPS location and then sends it every hour to reitti. With that i do not see that more power usage. Currently starting to test how the power drain is with a 15 seconds interval.

load more comments (4 replies)
[–] [email protected] 1 points 23 hours ago (1 children)
[–] [email protected] 1 points 23 hours ago
[–] [email protected] 9 points 1 day ago* (last edited 1 day ago) (1 children)

This looks good, I'm currently using dawarich and owntracks to track our families 5 week road trip around the south island of New Zealand (https://no.lastname.nz/post/1468113). If I can find a spare moment in our travels and a good internet connection I'll try and spin up an image and test it out.

One thing that I would love is to be able to have multiple people displayed on a single map (my wife [kids when they have their own phones with data], brother, mother and a few close friends - we already use google maps for this)

[–] [email protected] 7 points 1 day ago* (last edited 1 day ago) (1 children)

That sounds like an awesome idea, actually the data is stored for every user separately depending on the used api token or when you login and do a data import. I will create a feature request for it.

But bear in mind, reitti is not meant to be a real-time tracking app. At the moment, data is processed every 10 minutes.

load more comments (1 replies)
[–] [email protected] 4 points 1 day ago (1 children)

What's the difference from Dawarich, if I may ask? Beside from a better name :)

[–] [email protected] 6 points 1 day ago (2 children)

Thanks :) As a German I really like the name Dawarich. First it sound really nice for me but also that "Da war ich" means "There have i been" in german makes, at least for me, an awesome project name.

Take this with a grain of salt because I have no idea what the plans are for Dawarich or have ever been and this is solely based on my external view. For me the main differences are:

  • visits and trips are our main data, everything else is just the way to calculate them. For Dawarich it looks to me, that it is the other way around. It displays all the location data in good way with the heatmap and so on but visits or places seems so tacked on. This should not be an offense against it. I actually still have an instance running and it was the main pushing point to finally start working on Reitti.
  • the sleek UI but this depends on your taste

In the end, they are not that far off. Maybe a matter of taste.

[–] [email protected] 2 points 23 hours ago (1 children)

Maybe slightly off-topic, but how did you end up with the name "reitti"? You say you're German - do you have some sort of tie to the Finnish language?

[–] [email protected] 1 points 18 hours ago

Oh, i had the idea in mind what i want to create and than it was a matter of a couple of Google queries but in the end one of the LLM suggested a list of different names in foreign languages and reitti somehow sticked 😊

load more comments (1 replies)
load more comments
view more: next ›