Skip to main content

Postcodes and ZIP Codes

The question

The postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. looks like the friendliest part of an address. It is short, it is machine-readable, it has a fixed shape, and every form on the internet asks for it. So why is geocodinggeocodingThe process of converting an address into geographic coordinates (latitude and longitude). Mailwoman geocodes in a multi-tier cascade: exact address-point match → street interpolation → locality centroid. Each tier is progressively coarser but more widely available. by postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. the step that produces the coordinates you have to apologize for?

The analog

A postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. is a sorting instruction. It names a path through a postal network: which regional facility, which delivery office, which walk. It is written for the sorting machine and the carrier, and it encodes what they need in the order they need it.

The US structure runs from east to west. The first digit is "a general geographic area of the nation, '0' in the east, moving to '9' in the west"; the next two are regional areas; the final two are specific post offices (USPS). That is where the five digits stop — at a post office, not at a building. The +4 extension then names something smaller, and the Postal Service's own list of what it can name is the useful part: "a side of a streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. between intersectionsintersectionAn address that names a location by two crossing streets ('5th & Main') rather than a number and street. Mailwoman tags the two streets as intersection_a and intersection_b — a negative-space format that starved the early model., both sides of a streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. between intersectionsintersectionAn address that names a location by two crossing streets ('5th & Main') rather than a number and street. Mailwoman tags the two streets as intersection_a and intersection_b — a negative-space format that starved the early model., a building, a floor or group of floors in a building, a firm within a building, a spanspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree. of boxes on a rural route, or a group of Post Office boxesPO boxA numbered mailbox at a post office used as a delivery address instead of a physical street location. Mailwoman tags it as the po_box component; structurally the same family as a subpremise. to which a single USPS employee makes delivery" (Domestic Mail Manual 602). Two further digits, added in 1991, take it to the individual delivery point.

Every one of those is a delivery structure. None is a shape.

The same idea, five ways

Other postal services solve the same problem with different alphabets and different grain.

The UK splits the code into an outward half and an inward half, and the hierarchy is countable: 124 postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. areas, 3,118 districts, 12,463 sectors, and roughly 1.79 million live unitunitA subdivision of a building — apartment, suite, floor — that refines a street address. Mailwoman's unit component; a designator plus identifier forms a subpremise. postcodespostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one.. A small-user unitunitA subdivision of a building — apartment, suite, floor — that refines a street address. Mailwoman's unit component; a designator plus identifier forms a subpremise. postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. covers about fifteen addresses and never more than a hundred (ONS). At that grain a UK postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. is close to a point, which is why SW1A 1AA behaves in a geocoder like an address and 90210 does not.

Ireland went further. An Eircode is seven characters: a three-character routing key naming the post town, then a four-character unique identifier that "is unique to an address and its geographic location" (Eircode). One code, one delivery point, no interpolationinterpolationA geocoding technique that estimates a coordinate along a street segment based on the house number range. Used as the middle tier of Mailwoman's geocode cascade when exact address-point data is unavailable. required — and no code at all before the system launched in 2015.

Canada alternates letters and digits (K1A 0B1): a forward sortation area, then a local delivery unitunitA subdivision of a building — apartment, suite, floor — that refines a street address. Mailwoman's unit component; a designator plus identifier forms a subpremise.. The Netherlands writes four digits and two letters. France writes five digits whose first two are the département, which is why 06130 and 6130 are different places and a system that stores postcodespostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. as integers loses the difference.

Why the polygon is somebody's approximation

The habit of drawing a postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. as a shape comes from a real file, and the file says what it is. The US Census Bureau's ZIP Code Tabulation Areas exist because "ZIP Codes are stored as one component of discrete addresses tied to delivery points, including specific housing unitunitA subdivision of a building — apartment, suite, floor — that refines a street address. Mailwoman's unit component; a designator plus identifier forms a subpremise. locations. The result is a point-based dataset unsuitable for mapping …" (Census). The Bureau generalized census blocks into areas so that ZIP-keyed statistics could be mapped at all. The areas are the Bureau's construction, not a Postal Service boundary, and the same page states plainly that the Postal Service "assigns ZIP Code ranges to regional post offices, which in turn assign ZIP Codes to delivery routes."

The UK admits the same thing from the other direction: "postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. boundaries mostly do not align with other geographic boundaries," and they move as addresses are built and mail volumes change (ONS).

So the errors are structural rather than incidental. A rural code covers a route, and its centroid sits wherever the route's addresses happen to average out. A box-only code centers on the post office, not on the homes of the people who rent the boxes. A code that spansspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree. a town line belongs to two municipalities and neither of their outlines.

What this costs a parser

Two consequences, and they pull in opposite directions.

The first is that a postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. is strong evidence about a regionregionThe first-level administrative subdivision of a country — a US state, a French region, a province. The component between country and locality. and weak evidence about a point. Treated as a constraint on where to look, it earns its place; treated as an answer, it produces coordinates whose error is invisible in the output.

The second is that a postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. shape is not countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head.-unique. Five digits is the US pattern and the French pattern and part of the German one, so a bare 75001 is a question rather than a fact. Mailwoman's kind classifierkind classifierStage 2.5 of the runtime pipeline: categorizes the input into one of eight query kinds (structured_address, postcode_only, locality_only, intersection, po_box, landmark, poi_query, vague) so the coordinator can route to the right parsing strategy. will tell you it received a postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. and nothing else, and Handle PO boxes and other edge kinds carries the measured table of where five bare postcodespostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. resolved with no countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head. scope — four US codes, none of which came back in the US. That page also shows the fix, which is to scope the query, and the residual, which is that scoping turns some wrong answers into no answer.

  • What an address is — the delivery point the code routes to.
  • How mail gets delivered — the machines the code was designed for.
  • Falsehoods about addresses — the postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. section, in one line each.
  • Handle PO boxes and other edge kinds — what a bare postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. does in the pipelinestaged pipelineMailwoman's runtime architecture: a sequence of pure-function stages (normalize → query-shape → locale-gate → kind-classifier → phrase-grouper → classifier → decoder) connected by typed handoffs. Each stage is published as its own npm package. today.