Privacy policy
What this site collects, where it goes, how long it stays, and how to get rid of it.
Last updated August 25, 2026
What this covers
This is the privacy policy for dmvwaittimes.com, a public index of DMV office locations, opening hours and estimated wait times. It is written to be checked against the software rather than to sound reassuring, so it names the specific fields and the specific companies involved.
Nearly all of the site works without an account and without knowing who you are. You only need an account for wait alerts.
What we collect
Things you give us
- Your approximate location, only if you accept your browser’s permission prompt. The coordinates are held in the page while you are using it and sent to our server to find the nearest offices. We do not write them into our database, do not attach them to any record of your visit, and do not save them on your device — reload the page and it asks again. Two things we would rather state than hide: when we have no offices cached for the area you are in, your coordinates and search radius are forwarded to Google’s Places API so we can discover offices there; and that same code path writes your coordinates into our server log, where they remain for as long as our host keeps logs.
- Wait reports. When you report a wait we store the office, the number of minutes, the type of service and the time. That is the entire record: no name, no email address, no IP address, no link to an account. We cannot trace a wait report back to the person who sent it.
- Contact form messages. Your name, email address, subject and message. We also store the IP address the message arrived from and your browser’s user-agent string next to it.
- Your email address, if you create an account. It is what we send sign-in links to, and it is stored again on each alert you create.
Things collected automatically
- Your IP address, in transit. Every request passes through our hosting provider and our database provider, both of which see your IP address as an ordinary part of delivering a web page. We do not copy it into our own tables except for contact form messages, above.
- A rate-limit counter. To stop the site being flooded, your IP address is sent to Upstash and held there as a counter for the length of the limit window — between one and ten minutes. This is not only about forms: the office-lookup endpoint and the page-view counter are rate-limited too, so your IP address reaches Upstash during ordinary browsing.
- Error reports. When something breaks, a report goes to Sentry containing the page address, the error itself and technical context about the browser or server. We have not turned on Sentry’s option to attach personally identifying request data.
- Analytics, described in its own section below, because there are two different things going on and only one of them is anonymous.
Wait alerts and notifications
A wait alert needs an account, and two things get stored on our server to make one work.
Your email address
When you create an alert we save your account email address on that alert’s row in our database, next to the office and the minute threshold you chose. Your address is also held by Supabase’s authentication service, which is what sends your sign-in links.
Alerts are delivered by browser notification only. We do not currently send alert emails.
A push subscription
If you allow notifications, your browser hands us a push subscription. It is not your email address and not your name. It is two things:
- an endpoint address at your browser vendor’s push service — Google for Chrome, Mozilla for Firefox, Apple for Safari, Microsoft for Edge — which routes messages to one browser on one device;
- two cryptographic keys, so the message can be encrypted and only your browser can open it.
We store all of it as JSON on each of your alert rows. It identifies a single browser installation, which is close enough to identifying a device that it is worth saying plainly: anyone holding it could send a notification to that browser. It stays stored until you remove it or your browser invalidates it.
To send an alert our server posts the encrypted message to that endpoint, so your browser vendor’s push service can see that a message was sent to your browser and when. It cannot read the contents.
How to revoke both
- Turn off browser notifications on your account page. This deletes every stored push subscription on your account right away. Your alerts stay set, but nothing can be delivered.
- Remove an individual alert on the account page. That deletes the whole row, including the email address and the push subscription stored on it.
- Revoke notification permission for this site in your browser settings. That breaks the subscription at the source. When a delivery comes back permanently rejected we delete the stored subscription automatically.
- Delete your account on the account page, which removes the account, every alert, every stored email address on those alerts and every push subscription. That cannot be undone.
How we count visits
Two separate things run on this site and they are not equivalent.
Our own counter
When you open an office page we record one row: which office, whether it was a page view or a wait report, the hour of the day, the day of the week, and the moment it happened. That is the whole row, apart from the random id Postgres gives it. No IP address, no cookie, no device identifier, no account link — nothing that joins one page view to another or to you. It exists so we know which offices people actually use, and so the wait estimate has a signal for how busy a page is.
Google Analytics
The site also loads Google Analytics, which is a different thing entirely: it sets its own cookies, assigns your browser a visitor identifier and reports to Google. It is the thing the cookie banner asks you about, and it sends considerably more than page views:
- which office you clicked, its name, the wait shown for it and how far it was from you;
- when you open the report or alert dialogs, which office that was for, and how you moved through the search;
- how far down a page you scrolled, how long you stayed, and a score derived from that when you leave;
- what you type into a search box on this site, once it reaches three characters;
- the search phrase you typed into Google, if a Google result is what brought you here. Your browser passes that to us in the referrer and the analytics code forwards it.
Two limitations of how this is currently wired are worth stating plainly rather than leaving for you to discover.
First, until you answer the banner the Google Analytics script loads anyway. In the EEA and the UK it starts with analytics and advertising storage denied. Everywhere else it starts with analytics storage granted, so Google may set its cookies and record a page view before you decline. Clearing your answer puts you back into that state rather than into a quiet one.
Second, declining on the banner or on the cookie policy page takes full effect on your next page load rather than instantly. The listeners that collect the events above are attached when the page loads and are not detached when you change your mind, and the search-referral and typed-search tracking above is tied to whether the analytics script is present at all rather than to your answer. Reload the page after declining.
We do not run advertising and we do not sell data to anyone.
How long we keep things
We would rather describe what actually happens than quote a retention period nothing enforces. Two scheduled deletions exist, and nothing else is deleted automatically.
Deleted on a schedule
- Cached wait estimates, after seven days.
- A push subscription that a browser vendor reports as permanently gone, as soon as we see the rejection.
Kept until someone removes it
- Contact form messages, including the IP address and user-agent string stored with them. There is no automatic expiry and no deletion schedule: a message stays on file, IP address included, until someone removes it by hand. An earlier version of this policy said IP addresses were “retained briefly for abuse prevention”. That was not true, and this paragraph replaces it. If you want a message and its IP address removed, ask on the contact page and we will delete the row.
- Wait reports and the anonymous view and report counters. These carry no identifier at all and are what the published estimates are built from.
- Your account, alerts and push subscriptions, until you remove them yourself.
Who else handles it
These companies process data on our behalf. Naming them is the point of this section.
- Supabase — the Postgres database and the authentication service. Everything this policy says we store is stored there. Supabase also holds your account email address and sends your sign-in links.
- Vercel — hosting and content delivery. Serves every page and runs the scheduled jobs, and sees request metadata including your IP address.
- Upstash — Redis, used only for the per-IP rate limiting described above.
- Sentry — error and performance monitoring. Receives error reports containing page addresses and technical context.
- Google — in three separate roles. Google Places supplies office names, addresses and opening hours. Most lookups are answered from our own cache, but when we have nothing cached for the area you are searching, your coordinates and radius are sent to Google so we can find offices there. Google Analytics is described above. Google’s push service also carries notifications to Chrome, as each browser vendor’s push service does for its own browser.
Your choices
- Location — deny the prompt, or revoke the permission in your browser settings. Nothing is saved on your device either way.
- Analytics — decline on the cookie banner, or change your answer at any time on the cookie policy page.
- Notifications — turn off browser notifications on your account page, or revoke the site’s notification permission in your browser.
- Individual alerts — remove them on the account page.
- Your whole account — delete it on the account page. That removes the account, every alert, the stored email addresses and every push subscription, immediately and permanently.
- Contact messages — ask us and we will delete the message and the IP address stored with it.
Depending on where you live you may have further rights to see, correct, export or restrict what we hold about you. Ask on the contact page and we will deal with it.
Security
The site is served over HTTPS. Alert rows are protected by row-level security in the database, so a signed-in account can only read and write its own. Contact form messages cannot be read at all with the public database key — reading them needs a server-side credential. Administrative operations such as deleting an account use a server-only key that is never sent to a browser.
No system is perfect, and we are not going to claim this one is.
Questions
Use the contact page. As described above, a message sent that way stores your name, email address and message, along with the IP address it came from.