To put it in plain mathematical language, ZIP codes are not defined as polygons [0]. The consequence is that performing any analysis with an assumption that ZIP codes are polygons is bound to be error-prone.
That's not the important problem and there's a simple solution with ZCTAs.
The big problem is zip codes are defined in terms of convenient postal routes and aren't suitable for most geospatial analysis. Census units, as the article explains, are a much better choice.
> The consequence is that performing any analysis with an assumption that ZIP codes are polygons is bound to be error-prone.
Yeah, but any analysis you're likely to perform is approximate enough that the fact that ZIP codes aren't polygons is basically a rounding error.
Plus, it's a lot easier to get ZIP codes, and they're more reliably correct, so you might still get better results, than you would going with another indicator that is either (a) less reliable or (b) less available.
They aren’t reliable correct actually. The boundaries that the Census publishes are called Zip Code Tabulation Areas which are approximations of zip codes and include overlaps.
Yeah. ZIP codes are sets in the abstract-dimensional space of carrier delivery points. I suppose you could think of them as lines, but definitely not polygons.
Zip codes (in the US) are machine readable numbers a mail sorter can use to send a parcel to the right delivery truck for final delivery. In the US, they represent the hierarchy of postal centers with the most significant digit representing the primary hub for a region and the smallest number the actual post office that will be in charge of delivering the letter (or truck if you do the extended post code).
They don't represent geography at all, they represent the organizational structure of USPS.
They work by making the address on a letter almost meaningless. For some smaller population zip codes you can practically just put the name and zip code down and achieve delivery.
ZIP codes are an emergent property of the mail delivery system. While the author might consider this a bad thing, this makes them "good enough" on multiple axes in practice. They tend to be:
- Well-known (everybody knows their zip code)
- Easily extracted (they're part of every address, no geocoding required)
- Uniform-enough (not perfect, but in most cases close)
- Granular-enough
- Contiguous-enough by travel time
Notably, the alternatives the author proposes all fail on one or more of these:
- Census units: almost nobody knows what census tract they live in, and it can be non-trivial to map from address to tract
- Spatial cells: uneven distribution of population, and arbitrary division of space (boundaries pass right through buildings), and definitely nobody knows what S2 or H3 cell they live in.
- Address: this option doesn't even make sense. Yes, you can geocode addresses, but you still need to aggregate by something.
This is a tangent, but addresses are also way more complicated than most people realize - especially if you’re relying on a user to input a correct address or if you need to support multiple countries, somewhere with unique addresses like Queens[0], or you need to differentiate between units of a specific street address that uses something other than unit numbers for a unit designation.
At that point you need something like Smarty[1] to validate and parse addresses.
Just last week I had to deal with the fact that my house has the wrong address in multiple databases because things changed when an interstate went in 40-something years ago. It's not a big change--main st. vs N main st. but it was enough to mess up various things. Not as much as when I moved in 30 years ago but still enough to be wrong in old town and telco records. Took me a couple of days to get a permit issued to get electrical hooked back up after a fire as a result because apparently some town clerk insisted the address wasn't valid.
An annoyance for me is that I've yet to see any address validator get my current home address right. They all insist my address is on the road that leads to my road rather than my actual road. It's understandable that they can't be 100% accurate given the scale / complexity of addresses.
Most sites/apps will let me override the validator, but a few won't. The most common ones that insist on using the wrong address are financial institutions that say the law requires them to have my proper physical address and therefore they go with the (incorrectly) validated version.
USPS does not do home delivery in our area, and UPS/FedEx/etc. usually figure it out given that street numbers alone uniquely identify properties in our town.
Addresses are a huge ordeal in banking. Easily one of the most tortured domain types when it comes to edge cases and integration pain.
Every customer I've worked with insisted on having all addresses ran through the USPS verification API so they could get their bulk mailing discounts.
Even if you get the delivery/cost side under control, you still have to make sure you are talking about the right address from a logical perspective. Mailing, physical, seasonal, etc. address types add a whole extra dimension of fun.
Yes, unfortunately, their assertion that everyone knows their zip code is wrong. People often write a neighboring code, and the post office just delivers it.
Regarding article, it really depends on the use case of whether to use ZIP Code (TM), postal code, Canada Post Forward Sortation Area, lat/lon, Census Bureau block and tract, etc.
As has been noted, the ZIP Code is often good enough for aggregating data together and can be a good first step if you don’t know where to start.
There are point process models, but, yes, its much more common to want to aggregate to a spatial area.
Another consideration is what kind of reference information is available at different spatial units. There are plenty of Census Bureau data available by ZCTA but some data may only be available at other aggregate units. Zip Codes are often used as political boundaries.
I'd also mention the "best" areal unit depends on the data. There is a well known phenomenon called the modifiable areal unit problem in which spatial effects appear and vanish at different spatial resolutions. It can sort of be thought of as a spatial variation of the ecological fallacy.
One more advantage: ZIP codes are a good trade-off if you want to gather anonymous data in a survey or provide anonymized data to an outside entity. For example, we recently conducted a survey on mobility patterns within our university. To offer respondents a reasonable amount of anonymity, we just asked for their (German) ZIP code and the location of their primary workplace.
This allows us to determine the distance and approximate route people would take between home and university campus - to a degree that is sufficient for our goals.
Well you hit on all the points that discuss the compromises that zip codes offer. Just because you have them in your data doesn't mean that they can produce anything useful. You are correct that no one knows their census unit is (if you are thinking from someone entering this on a website) but collecting location or address will be a lot better.
Fact is a lot of web data contains a zip but if you can collect something better it will usually render better results. Unless you are analyzing shipments then that is fine.
In terms of "good enough", a Canadian postal code, broadly equivalent to a zip code, is much more granular and can often identify an individual apartment building, or single city block. Plenty of large office buildings in major Canadian cities also have their own postal code.
The functionality of it is closer to the "Zip+4" with extension used to have a more granular routing of physical mail for USPS.
Sure, and in the States, ZIP+4 could once nail my postal location to a subset of 4 (of a group of 16) mailboxes within a particular set of entry doors on a particular apartment building.
But broadly speaking, nobody knows what their ZIP+4 is, while I imagine that most people in Canada know their postal code by heart.
> In terms of "good enough", a Canadian postal code, broadly equivalent to a zip code, is much more granular and can often identify an individual apartment building, or single city block.
To the point that StatCan and other agencies have rules on the number of characters that are collected/disseminated with other data to make sure it's not too identifying:
If you are worrying about address at all instead of tax or legal jurisdiction its probable that you as a business have a physical presence. You can probably correlate better by predicting which location a given address would likely interact with if you don't know already by prior purchases/interaction which they normally do so. I would suggest actual purchase data followed by travel time.
Zip and distance as the crow flies often gives shit data. My zip suggests I'm off in bum fuck and since I'm on the puget sound things that are relatively near as the crow flies can actually be hours away.
> Easily extracted (they're part of every address, no geocoding required)
That's only true if you can also access the spatial boundaries of the zipcodes themselves.
In Australia, this turns out not to be true: the postal system considers their boundaries to be commercial confidential information and doesn't share them. The best we can do is the Australian Bureau of Statistics' approximations of them, which they dub "postal areas".
Also, "use a different grid" is only masking the problem, not actually fixing it.
The real problem is ever using an average without also specifying some sort of bounds. For median-based data, this probably means the upper and lower quartiles (or possibly other percentiles); for mean-based data, this probably means standard deviation.
On the note of census units, the only reason we all know our zipcode is because we have to know it. If census units were used as frequently as zip’s I imagine they would quickly become more widely known as well.
Contiguous enough by data travel time as well. A few people will get 5 ms more latency than the exact optimal route, but it’s not like your routes are exactly optimal anyway.
And don’t forget sales tax. Which is state + county + city
I've noticed more and more super/hypermarkets started asking for your zip/postal code sometime during self-checkout. I'm guessing they use these as approximations about where people travel from, so they can evaluate if to open more stores closer to popular areas, or something like that. Pretty sure there is more use cases for postal codes too.
Postcodes are very useful (but not perfect) proxies for household socioeconomic status, which is useful for marketing and sales analysis.
That data linked with the payment method that the register collects pretty much gives the store exactly who you are and where you live even if you chose not to sign up to the store's loyalty program.
That's what I was thinking of earlier, the succinct version is "your address is where mail needs to go, the zip code is how to get it there". Or in other words, the zip code is the address(es) of the sorting centers and post offices to the destination.
Great article. Zip codes can be super expedient. But you have to be self aware that for many uses cases they function WORSE than a random grid. Because they have built-in aggregation of a central post office(and surrounding) with a certain radius of rural/less dense surrounding.
So for example, if you are sorting “rural zips” vs “urban zips” it will only take you so far, and may actually be harmful.
Same goes with MSAs/DMAs (media markets). These have to be used for buying media, but for geospatial analysis they are suboptimal for the same reasons.
Easiest way to dip your toe into the water of something better is to start with A-D census counties.
If you want to learn a bit more, there was a recent, really good Planet Money episode[1] about this exact same topic. They focus on the problems that you might face when using zip code for demographic analysis.
H3 is awesome here! What I don't think many people realize is that H3 cells and normal geographic data (like zips) are not mutually exclusive. You can take zip outlines, and find all the h3 cells within them and allocate your metric accordingly (population, income, etc).
This makes joining disparate data sources quite easy. And this also lets you do all sorts of cool stuff like aggregations, smoothing, flow modeling, etc.
We do some geospatial stuff and I wrote a polars plugin to help with this a while back [1].
0: https://manifold.net/doc/mfd8/zip_codes_are_not_areas.htm
The big problem is zip codes are defined in terms of convenient postal routes and aren't suitable for most geospatial analysis. Census units, as the article explains, are a much better choice.
Yeah, but any analysis you're likely to perform is approximate enough that the fact that ZIP codes aren't polygons is basically a rounding error.
Plus, it's a lot easier to get ZIP codes, and they're more reliably correct, so you might still get better results, than you would going with another indicator that is either (a) less reliable or (b) less available.
They don't represent geography at all, they represent the organizational structure of USPS.
They work by making the address on a letter almost meaningless. For some smaller population zip codes you can practically just put the name and zip code down and achieve delivery.
- Well-known (everybody knows their zip code)
- Easily extracted (they're part of every address, no geocoding required)
- Uniform-enough (not perfect, but in most cases close)
- Granular-enough
- Contiguous-enough by travel time
Notably, the alternatives the author proposes all fail on one or more of these:
- Census units: almost nobody knows what census tract they live in, and it can be non-trivial to map from address to tract
- Spatial cells: uneven distribution of population, and arbitrary division of space (boundaries pass right through buildings), and definitely nobody knows what S2 or H3 cell they live in.
- Address: this option doesn't even make sense. Yes, you can geocode addresses, but you still need to aggregate by something.
At that point you need something like Smarty[1] to validate and parse addresses.
[0]: https://stackoverflow.com/questions/2783155/how-to-distingui...
[1]: https://www.smarty.com/
Most sites/apps will let me override the validator, but a few won't. The most common ones that insist on using the wrong address are financial institutions that say the law requires them to have my proper physical address and therefore they go with the (incorrectly) validated version.
USPS does not do home delivery in our area, and UPS/FedEx/etc. usually figure it out given that street numbers alone uniquely identify properties in our town.
Every customer I've worked with insisted on having all addresses ran through the USPS verification API so they could get their bulk mailing discounts.
Even if you get the delivery/cost side under control, you still have to make sure you are talking about the right address from a logical perspective. Mailing, physical, seasonal, etc. address types add a whole extra dimension of fun.
Similar issues for city name, of course.
Regarding article, it really depends on the use case of whether to use ZIP Code (TM), postal code, Canada Post Forward Sortation Area, lat/lon, Census Bureau block and tract, etc.
As has been noted, the ZIP Code is often good enough for aggregating data together and can be a good first step if you don’t know where to start.
Another consideration is what kind of reference information is available at different spatial units. There are plenty of Census Bureau data available by ZCTA but some data may only be available at other aggregate units. Zip Codes are often used as political boundaries.
I'd also mention the "best" areal unit depends on the data. There is a well known phenomenon called the modifiable areal unit problem in which spatial effects appear and vanish at different spatial resolutions. It can sort of be thought of as a spatial variation of the ecological fallacy.
Fact is a lot of web data contains a zip but if you can collect something better it will usually render better results. Unless you are analyzing shipments then that is fine.
The functionality of it is closer to the "Zip+4" with extension used to have a more granular routing of physical mail for USPS.
https://www.canadapost-postescanada.ca/cpc/en/support/articl...
https://en.wikipedia.org/wiki/Postal_codes_in_Canada
But broadly speaking, nobody knows what their ZIP+4 is, while I imagine that most people in Canada know their postal code by heart.
It is interesting.
To the point that StatCan and other agencies have rules on the number of characters that are collected/disseminated with other data to make sure it's not too identifying:
* https://www.canada.ca/en/government/system/digital-governmen...
* https://www12.statcan.gc.ca/nhs-enm/2011/ref/DQ-QD/guide_2-e...
Zip and distance as the crow flies often gives shit data. My zip suggests I'm off in bum fuck and since I'm on the puget sound things that are relatively near as the crow flies can actually be hours away.
That's only true if you can also access the spatial boundaries of the zipcodes themselves.
In Australia, this turns out not to be true: the postal system considers their boundaries to be commercial confidential information and doesn't share them. The best we can do is the Australian Bureau of Statistics' approximations of them, which they dub "postal areas".
The real problem is ever using an average without also specifying some sort of bounds. For median-based data, this probably means the upper and lower quartiles (or possibly other percentiles); for mean-based data, this probably means standard deviation.
And don’t forget sales tax. Which is state + county + city
CGP Grey has a great video on this: https://m.youtube.com/watch?v=1K5oDtVAYzk
That data linked with the payment method that the register collects pretty much gives the store exactly who you are and where you live even if you chose not to sign up to the store's loyalty program.
* https://www.youtube.com/watch?v=1K5oDtVAYzk
So for example, if you are sorting “rural zips” vs “urban zips” it will only take you so far, and may actually be harmful.
Same goes with MSAs/DMAs (media markets). These have to be used for buying media, but for geospatial analysis they are suboptimal for the same reasons.
Easiest way to dip your toe into the water of something better is to start with A-D census counties.
[1]: https://www.npr.org/2025/01/08/1223466587/zip-code-history
This makes joining disparate data sources quite easy. And this also lets you do all sorts of cool stuff like aggregations, smoothing, flow modeling, etc.
We do some geospatial stuff and I wrote a polars plugin to help with this a while back [1].
[1] https://github.com/Filimoa/polars-h3