Over the past few years, I’ve had a number of trips driving within or through the Washington, D.C. metro area. The Capital Beltway (Interstate 495) encircles Washington, passing through Maryland, Virginia, and a tiny corner of D.C. itself.

I-495, the Capital Beltway. (I-95 is also concurrent with the eastern half of the beltway.)
Basemap © Mapbox © OpenStreetMap (Improve this map)
The Capital Beltway is a busy road, with many complicated interchanges, local/through lanes, and tolled express lanes. I started to wonder if there was any way to circle all the way around the beltway, ending up back where I started, without changing lanes.
Table of Contents
Problem Statement
- Do any lanes entirely circle the beltway, in either direction? (Trivial loops, such as taking four leaves of the same cloverleaf, do not count. The loop must entirely circle central D.C. along I-495.)
- If so, does the driver end up in the same lane position (e.g. the leftmost lane), or does the lane spiral into a new position?
What Is a Lane?
For this project, I define a lane as a continuous stretch of road between two painted lines (solid or dashed) that approximately parallel the direction of travel.
A and B are both lanes.
If multiple lanes merge without needing to cross a painted line, each path counts as staying in the same lane.1 Likewise, if a lane splits into multiple lanes without needing to cross a painted line, each path counts as staying in the same lane.
C→E, D→E, F→G, and F→H would each count as staying in the same lane.
If a lane split does require crossing a painted line, the other side of the paint is considered a new lane starting at that point. Likewise, if a lane merge does require crossing a painted line, the lane that must cross paint simply ends at that point.
J→L and P→Q would each count as staying in the same lane. Lane K ends, and R is a new lane.
Informational paint symbols (such as text, route shields, merge arrows, etc.) are not considered painted lines, and lanes continue across them.
How to Circle the Beltway
Based on Google Earth imagery and Street View data from April 2025 (the latest available at the time of this writing), I was able to find three lanes that entirely circle the Capital Beltway—two in the counterclockwise direction, and one in the clockwise direction.
I-495 Outer Loop (Counterclockwise)
The diagram below shows the Capital Beltway’s outer (counterclockwise) loop “unrolled” into a straight line. The top connects to the bottom to represent a complete circle. Start at the bottom and work your way up!

Minimap basemaps © Mapbox © OpenStreetMap (Improve this map)
There are two separate lane paths that will loop around the outer beltway and end up back at the same location without changing lanes (though both will end up in a different lane from where they started).
Path A
- In Northern Virginia, just before the E-ZPass Express Lanes split off to the left, a new lane will start as the leftmost of five lanes. Start in this new lane.
- Follow this lane into the E-ZPass Express Lanes.
- West of the Springfield Interchange, the two E-ZPass Express Lanes will merge back into the main lanes. you’ll be in the far left lane.
- As you approach the Springfield Interchange, this left lane will take a left exit to E-ZPass Express Lanes toward I-395 North and I-95 South.
- Stay in this express lane, but do not take the exits to either I-395 North or I-95 South. Instead, continue on the Express Lane toward I-95 North and I-495 East (Baltimore).
- This lane will eventually rejoin the beltway, and will take you into and through Maryland.
- You will end up back where you started in Northern Virginia just before the E-ZPass Express Lanes split, but in the rightmost lane.
- As the E-ZPass Express Lanes split off to the left, this rightmost lane stays in the standard I-495 lanes. Keep following this lane, and always stay on I-495 when you have the option to exit.
- When the E-ZPass Express Lanes rejoin west of the Springfield Interchange, you will once again be on the same road segments you were on before, but in the rightmost lane.
- This path leaves the beltway onto I-95 South at the Springfield Interchange.
Path B
- Enter the beltway from southbound I-270 Spur, in the leftmost lane. This becomes the leftmost lane of I-495.
- When the E-ZPass Express Lanes start in Northern Virginia, stay left into the right express lane.
- West of the Springfield Interchange, the two E-ZPass Express Lanes will merge back into the main lanes. you’ll be in the second lane from the left.
- After the Springfield Interchange, you will end up in the third lane from the left. Stay in this lane through Maryland.
- As you approach the split to I-270 North (Frederick), stay left onto I-495 West (Northern Virginia).
- When I-270 Spur merges in from your left, you’ll be back where you started, but in the right lane.
- Take Exit 39 toward River Road, and keep staying straight on this exit lane. The lane will eventually merge back onto the beltway after the Cabin John Parkway (and will end up in the same lane as Path A).
- From this onramp through the E-ZPass Express Lanes left exit, you will once again be on the same road segments you were on before, but in the rightmost lane.
- As the E-ZPass Express Lanes split off to the left, this rightmost lane stays in the standard I-495 lanes. Keep following this lane, and always stay on I-495 when you have the option to exit.
- When the E-ZPass Express Lanes rejoin west of the Springfield Interchange, you will for a third time be on the same road segments you were on before, but in the rightmost lane.
- This path leaves the beltway onto I-95 South at the Springfield Interchange.
I-495 Inner Loop (Clockwise)
Likewise, this diagram shows the Capital Beltway’s inner (clockwise) loop “unrolled” into a straight line. The top connects to the bottom to represent a complete circle. Start at the bottom and work your way up!

Minimap basemaps © Mapbox © OpenStreetMap (Improve this map)
The inner loop has a single lane path that loops back to where it started, labeled as Path C.
Path C
- Start on the Springfield Interchange onramp from I-95 North and I-395 South to I-495 North (Tysons Corner). Be in any of the three right lanes.
- After this ramp merges into the beltway, all three of these right lanes gradually merge into a single rightmost lane. Stay in this lane.
- As the E-ZPass Express Lanes split off to the left, this rightmost lane stays in the standard I-495 lanes. Keep following this lane, and always stay on I-495 when you have the option to exit.
- By the time the E-ZPass Lanes merge back into the main lanes, you’ll be in the second lane from the right. Stay in this lane into Maryland.
- At Exits 25B–A (U.S. Route 1), either stay on I-495 or take the exit. Both of these lanes will merge again after the U.S. Route 1 interchange and end up as the rightmost lane on I-495.
- At Exits 17–16, this lane will exit into the local lanes and split into two lanes. Stay in either of these two local lanes, but do not take any of the exits. These two lanes will merge after Exit 16 and rejoin the main lanes of I-495.
- Continue in this lane through Maryland and into the Springfield Interchange.
- When the I-95 North/I-395 South ramps merge onto I-495 Inner, you’ll be back where you started, but in the third lane from the left. You will continue to travel on road segments you’ve been on before all the way to the left exit for Virginia Route 267 West (Dulles Airport).
- This path leaves the beltway on the left exit toward Dulles.
Since this road heads towards Dulles airport, I was curious if the path might go all the way to Dulles Airport, traverse the arrival/departure loops, and return back on Virginia Route 267 East to the beltway. The lane does get to Dulles, but can only get to either the Economy Parking entrance next to the gas station, or Autopilot Drive toward rental car return. It does not loop back to the Capital Beltway.
Technical Details: How I Found the Loops
I initially thought that I could use OpenStreetMap lane data. I wrote some simple scripts, but eventually realized that while OpenStreetMap works reasonably well for getting a lane count at any given portion of well-traveled roadways, it didn’t consistently provide which lanes in one segment connected to which lanes in the next segment. Commercial lane data exists, but only at commercial licensing prices, and I couldn’t find an API that would provide it to me with per-query costs.
Because my scope was limited to a single major beltway and the ramps immediately connected to it, I decided to create my own lane connection data from aerial imagery and street view data. But first, I’d need to decide how to store it.
Directed Graph of Lanes Concept
I started by defining a road segment as a stretch of road where the lanes don’t change. From start to end, it keeps the same number of lanes in the same directions—no lanes starting, ending, merging, splitting, entering the road, or exiting the road. To identify them, each road_segment
has its own unique ID number. Thus, whenever the number of lanes changes (splits, merges, entrances, exits), a new segment starts.
Each segment therefore has a consistent number of lanes along its length. Within each segment, each lane is assigned a number starting with 0 for the left lane. (For example, a three-lane one-way road has lanes 0, 1, and 2).2
Every time the number of lanes changes, a new segment starts.
In the above image, Segment 0 Lane 0 ((S0,L0)
) connects to (S1,L0)
, which then connects to (S2,L0)
. (S0,L1)
and (S0,L2)
both connect to (S1,L1)
, which then connects to both (S2,L1)
and (S2,L2)
.
This forms a directed graph where each (segment, lane) pair is a node and each connection is a directed edge.
Of course, with entrances (on-ramps) and exits (off-ramps), multiple segments can connect to a single segment, and a single segment can connect to multiple segments.
With a directed graph of how each road segment’s lanes connect to other road segments’ lanes for the entire Capital Beltway, each path through the graph represents a way to traverse the beltway without changing lanes. This lets us answer the problem statement above:
- If any paths contain two nodes with the same road segment ID, then it’s possible to circle the beltway and end up at the same road segment.
- If any paths form a directed cycle (returning to the same road segment ID and lane number), then it’s possible to circle the beltway and end up in the same lane.
Obtaining Road Geometry
Although I couldn’t use OpenStreetMap’s lane data, OpenStreetMap was still useful for the geometry (location and shape) of the road segments I needed.
First, I downloaded the latest D.C., Maryland, Virginia .osm.pbf
files from Geofabrik.
To process the files, I used Osmium Tool and GDAL’s ogr2ogr. Because my primary system runs Windows and Osmium Tool doesn’t offer Windows binaries, I installed these tools into WSL:
$ sudo apt update $ sudo apt install osmium-tool $ sudo apt install gdal-bin
I merged the D.C., Maryland, and Virginia files into a single file:
$ osmium merge district-of-columbia-latest.osm.pbf maryland-latest.osm.pbf virginia-latest.osm.pbf -o dcmdva.pbf
I cropped the data to a longitude/latitude rectangle that encompassed the Capital Beltway plus some margin:
$ osmium extract -b -77.35,38.70,-76.75,39.05 dcmdva.pbf -o dc_bbox.pbf
I filtered the data to roads only:
$ osmium tags-filter dc_bbox.pbf -o road_segments.pbf w/highway=motorway,trunk,primary,secondary,tertiary,unclassified,residential,living_street,service,motorway_link,trunk_link,primary_link,secondary_link,tertiary_link
Finally, I converted the .pbf file to a GeoPackage file:
$ ogr2ogr -f GPKG road_segments.gpkg road_segments.pbf lines -nln roads
Under the hood, a GeoPackage file is an SQLite database. Within this database is a table of road_segments
, each containing LineString geometry and indexed with a Feature ID (fid
). I used the fid
as my road segment ID in the directed graph.3
Building Connectors
To keep my data in one place, I decided to put the directed graph data in a non-geometry connectors
table in the same GeoPackage. Each row in the table represents an edge on the directed graph, with columns for from_segment_fid
, from_lane_number
, to_segment_fid
, and to_lane_number
. The _segment_fid
columns used the values from the fid
(feature ID) column in the road_segments
geometry table.
For example, this roadway and graph (repeated from above) would be encoded as follows:
from_segment_fid | from_lane_number | to_segment_fid | to_lane_number |
---|---|---|---|
3 | 0 | 5 | 0 |
3 | 1 | 5 | 1 |
4 | 0 | 5 | 1 |
5 | 0 | 6 | 0 |
5 | 0 | 7 | 0 |
5 | 1 | 7 | 1 |
I loaded the road_segments
table into QGIS to show me the location and fid of each road segment. Using Mapbox, Google Earth, and Google Street View as a reference, I worked my way around the beltway in both directions and filled out the connectors table.
Traversing the Directed Graph
Now that I had all of the lane connectors documented, I wrote a Python script to build a directed graph and look for returns to the same road segment.
Using the NetworkX package, my script loops through the connectors
table and builds a directed graph.
Since this is a directed graph with edges following the direction of travel, each node’s descendants represent all of the segment-lane pairs that you can possibly travel to from that given segment-lane without changing lanes. Thus, my script loops through each node and finds any that have descendants with the same segment fid
, and outputs the results as a table. It also adds attributes to the nodes, setting is_seg_loop_source
for each node that has a descendant with a matching segment fid
, and is_seg_loop_target
for each node that is the descendant of an ancestor with a matching segment fid
.

A partial sample of the output data. For each segment that can travel to itself without changing lanes, the table shows which source lane can travel to which target lane. For example, it’s possible to drive from Segment 47660 Lane 0 to Segment 47660 Lane 4 without changing lanes.
Next, my script takes all of the found matching ancestor/descendant node pairs, and uses the all_simple_paths
algorithm to add an is_path
flag to all nodes which are on any path between any source/target pairing. Doing this allowed me to trace how exactly I traverse the Capital Beltway to get from a segment back to itself.
Finally, the script outputs the graph and its node metadata to a GraphML file. This let me review the graph in yEd Graph Editor. I highlighted the flagged nodes in yEd, then used their segment fids to look up their geometry in QGIS, and built the lane following graphics from there.
Conclusion and Future Work
Building this graph of 3 529 nodes (road segment/lane pairs) and 3 431 edges (connectors) confirmed to me that, at least as of April 2025 imagery, it’s possible to circle the Capital Beltway in both directions without crossing any lane lines.
With more lane data, I would have liked to follow the lanes that departed the beltway to see if they’d rejoin the beltway at some point. For example, could a lane exit onto I-395 toward Washington D.C., continue on I-695 and I-295, and rejoin the beltway? Or in an even bigger circle, could a lane exit onto a highway heading away from D.C., and eventually follow some circuitous route to end up back in the D.C. metro area? Unfortunately, my solution space could conceivably involve any highway in North America, and building the lane data for the beltway alone took several hours of manual research, so it’s not practical without access to some sort of commercial lane data source.
A more reasonable future project might be to look at some other cities’ beltways. I live relatively near Cincinnati, whose I-275 beltway is one of the longest beltways in the country, and traverses three states (Ohio, Kentucky, and Indiana). I’d be able to go check my results with a quick day trip!
-
Even if it would be technically possible for a driver to weave between the dashes of a dashed line at low speed without actually touching paint, crossing a dashed line in this manner still counts as crossing a painted line. ↩︎
-
Road segments could possibly have lanes in two directions, either because it’s a two-way surface street or because it has reversible lanes. In that case, I would have numbered the reverse lanes with negative numbers (see Lane Numbering). In practice, I didn’t need to do this; the Capital Beltway itself and its ramps are one-way, and the reversible ramps at the Springfield Interchange to I-95 and I-395 clearly entirely left the beltway, so I didn’t include them in my lane dataset. ↩︎
-
The
road_segments
table also has anosm_id
column, representing the way ID in OpenStreetMap. I opted not to use it, as it would not remain unique if I ever needed to split a LineString locally. ↩︎