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
I’ve got a question about how reitti calculates significant places/visits.
I was thinking of adjust gps logger so that it doesn’t log points if they’re within 10m of the last point it logged. That will clear up the data when I’m at home or work, so that there is less of a random squiggle of location data. It will record me arriving at home, and leaving home, but not much in between.
Will that impact how reitti calculates locations though? Is it looking at the number of points, or is it simply a matter of duration within a particular vicinity?
Hi ada,
yes, this will impact the visit calculation. Visits are calculated in building clusters of at least 5 points in a range of 100m over a duration of at least 5 minutes. If there is only one point logged for example at work or home, Reitti is not able to detect when you left it because every point is just an instant in time and does not carry any duration information with it.
The more points we have to calculate Visits the more accurate it will be. I personally have set up GPSLogger to log every 30 seconds no matter how far I travelled but with at least 40m of accuracy.
This is really neat, I’m going to spin it up tomorrow!
Let me know how it worked out. I am deploying it to my server via docker without an problems, but maybe they are some quirks i missed. :D
Of course, happy to do so. I’ll report back with my experience when I have it working!
Man. I have no use for this. I know where I go. I go to work. And then the gym. Almost every day. Because I work a lot.
It’s like my boss always says…“BACK TO WORK, DICKHEAD!”
Cool!
I love the UI for this one, it’s unique compared to the others
Thanks otter, I tried to have a historical look. Like going to the past and revive some memories. Hope it worked out. I am actually pretty happy with it.
This looks amazing, congratulations and thank you for making it FOSS. I was wondering if you are considering integrating with Home Assistant.
Thanks :)
No, did not occur to me. What would the integration look like? Connecting it to the message bus to receive location updates? Honestly it is a couple years ago I played with HA.
I have the HA app on my phone, it reports my location back to my HA server.
I would like if Reitti could retrieve my location from my HA server, instead of asking me to upload it again to Reitti. Uploading my location in short intervals drains the battery very fast, it’s something I want to avoid if I can.
Additiinally, I don’t want to expose anything to the internet. So I pay for the Home Assistant cloud subscription that does it for me in a more secure manner than what I could implement with the little free time I have. Reitti could retrieve my location more securely if it did so without exiting my LAN.
I had a similar setup with Home Assistant in the past so I understand your usecase. For Reitti to detect visits somewhat reliable it needs at least one datapoint of location data a minute. We build location clusters with minimum 5 points in 5 minutes. If HA tracks that often it should work. HA probably tracks more than that.
I could add an integration that Reitti fetches the data from Home Assistant. Do you mind in creating a feature request?
Do you mind in creating a feature request?
Done 👍🏻
Location sensor would be a good minimum bar.
A custom card for your app that is just basically a iframe into your app with auth would also be pretty decent. Your version of a map looks really nice.
Maybe surfacing metrics of distance traveled or number of geolocations.
I’ll have to install the app and play around with it to make other recommendations but those are the first things that come to mind.
Home automation using geofencing, and my partner likes to get a notification when I’m heading home from the office
I’ve been putting off setting up an immich server. Would this do well if hosted on the same machine?
What’s the difference from Dawarich, if I may ask? Beside from a better name :)
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.
Thanks for the reply! I will give it a go :)
The word dawarich does not produce a polite sound in my main language, meant no offense to the project :)
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?
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 😊
I managed to break our instance. I imported several years worth of google takeout location data, and now the “stay-detection-queue” is stalled.
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 🙂
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.
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
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.
i7-8700 with 64GB of RAM
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.
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
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.
I still have a phone containing Google, and cannot change this situation (maybe with my next phone). Usually, I switch off location services very often and I avoid such tracking apps because all my data goes to Google then.
Would it be advisable to use this at all before I get rid of Google?
Hello @Zwuzelmaus@feddit.org, i usually use GPSLogger for Android to track my location during the day and this periodically sends the data to reitti whenever i am back at home. I have no idea if you switch off location services what happens on the GPSLogger side of the chain. If it still be able to access GPS I see no problem, if not than this sadly will break the usecase for reitti.
It relies on a consistent GPS tracking data to be able to do its thing
if you switch off location services
…then no app gets a location anymore.
This looks really cool! I just have one question. Is it possible to just install this like normal software on a Linux machine or does it require Docker?
Thank you.
At the moment i do not have any plans of providing a way of running it without docker. Mainly because of time to support that.
Since it is a Spring-Boot-Application it would be possible to create a jar file which you can execute or deploy as a service with systemd. But then you have to make sure all prerequisites are also running. That is the one thing I like about docker and especially docker compose.
But short answer: Yes, it is possible but you are on your own at the moment. I would help and maybe we can add a section to the readme how to do it.
Not sure if you know about it and I haven’t used it myself yet, but being able to create native executables could be relatively easy with this
https://docs.spring.io/spring-boot/reference/packaging/native-image/index.html
I used that once on a past gig and it wasn’t very pleasant to use. Especially in combination with spring boot. But that is a couple of years ago. Maybe things have changed. I personally would prefer the executable jar from spring boot. With that you do not have to make that many steps to make it work. But thanks for the suggestion :)
Hell yes! I turned off location data for immich but now I can use this!
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 :)
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.
Hi LazyToad,
it depends. Reitti on its own does not import any pictures. It only shows fetches them from Immich. For that to work it needs the geolocation where the image was taken in the exif data. You need to check if your expected image has this data in Immich. If it is available it shoud be displayed on the map if you select the day the picture was taken.
Does it show the location in Immich? You can verify this if you open the image in Immich and let it display the Info.
If it is showing, then it still could be that it is a bug in Reitti. Feel free to open an issue then :)
Thank you for testing Reitti. 🙏
It depends on two key requirements for Reitti:
- First, it finds all photos from Immich taken on the day you selected.
- 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.
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.
Glad I could help :)
This is really awesome! I was just about to start looking for something like this, so great timing. Going to get this up on my Unraid server tomorrow and play around with it
Docker-dependent? It looks fantastic, but I have no containers in my home-lab – and it’s based on my time managing OS security for an OS. I’m stuck living vicariously through the rest of you, so report back often.
Great project! Any recommendations for an iOS app for this? I’ve been using OwnTracks, but it works very unreliably. As far as I understand, it’s an OS problem since Apple allows for very limited background processing for the sake of saving battery, so there’s not much any logging apps can do, but I was just curious if someone found a way around it.
Not really, I stopped using IOS a year ago because of exactly this reason. Had a lot of problems syncing files because of the power saving. I understand why IOS is doing it and for a normal user I think it is the way to go. But anything beyond that, it only hinders the experience you get out of apps. Maybe someone here as any experience with an app which works reliably.