BGP Deep Dive Part 4: The Best Path Algorithm, Step by Step

Part 3 laid out the attribute catalog. This post is what a BGP speaker actually does with it: the ordered comparison chain that turns a table full of candidate routes to the same prefix into exactly one best path.

RFC 4271’s Decision Process is a foundation, not a fixed list

RFC 4271 splits path selection into two phases. Phase 1 calculates a degree of preference for each route, primarily by reading LOCAL_PREF for iBGP-learned routes or applying local policy to eBGP-learned ones. Phase 2 is where the actual comparison happens: given multiple candidate routes to the same destination, work through a defined sequence of tie-breaks until exactly one remains. What the RFC does not do is mandate one single, universal, step-by-step list that every implementation must follow in the same order. It defines the phases and the attributes available to them; the specific ordered chain is left to the implementation, within the constraints the RFC sets.

In practice, that’s produced a de facto standard: Cisco’s documented 13-step algorithm is the version most engineers learn first, it’s the most widely published, and every other major implementation is a variation on the same core sequence rather than something unrecognizably different. This post walks that Cisco ordering as the reference case, since starting from a shared baseline makes the vendor differences worth naming, not because it’s the only correct order. When the vendor-implementation parts of this series get written, FortiOS and Junos’s specific tie-break orders and terminology will get their own treatment against this same baseline.

One rule holds regardless of vendor: this is evaluated top to bottom, and the first step that leaves exactly one route standing ends the process. Every step before Weight and after the final tiebreak is either “there’s already a winner, stop” or “still tied, keep going.”

1. Highest Weight

Weight is Cisco-proprietary, not a BGP attribute at all, not advertised, not carried in any UPDATE message, and not something a Juniper or FortiOS box has any concept of. It’s a purely local value, set by policy on the router evaluating the path, and it exists specifically to let an administrator override every other consideration for routes matching a particular filter. Routes originated locally by the router itself default to a weight of 32768; everything else defaults to 0. Because it’s evaluated first and it’s entirely local, Weight is also the least portable piece of policy in this whole algorithm: it cannot be signaled to any other router, which is exactly why it sits outside the RFC’s actual attribute set.

2. Highest LOCAL_PREF

This is the first attribute-driven step, and it’s the one covered in Part 3 that’s meant to represent an AS’s actual policy preference among its own eBGP-learned entry points, propagated to every iBGP peer. Higher wins. Since LOCAL_PREF defaults to 100 across implementations that follow Cisco’s convention, two routes that haven’t had it explicitly set will tie here and fall through.

3. Prefer locally originated routes

A route the local router originated itself, via a network statement, redistribution, or aggregation, is preferred over a route learned from a BGP peer, even before comparing AS_PATH length. This step rarely decides anything in a typical transit scenario, but it matters for exactly the aggregation case Part 3 covered: a router that both originates an aggregate and hears a more general path to a covered prefix from a peer will prefer its own aggregate here.

4. Shortest AS_PATH

This is the step most people think of as “the” BGP metric, and it’s genuinely just a count: the number of AS hops in the AS_PATH attribute from Part 3, with an AS_SET counted as a single hop regardless of how many AS numbers it contains. Shorter wins. This is also the step AS_PATH prepending exists to manipulate, covered properly in Part 9’s traffic engineering post: artificially lengthening the AS_PATH announced to one peer is a direct, deliberate attempt to lose at this exact step, in order to steer inbound traffic toward a different, unprepended path instead.

5. Lowest origin type

ORIGIN, from Part 3, breaks ties in the order IGP, then EGP, then INCOMPLETE. In practice EGP is close to extinct on the modern internet, so this step is really IGP-originated routes beating routes learned via redistribution that BGP couldn’t fully vouch for.

6. Lowest MED

MED comparison carries a rule worth restating from Part 3: it’s only meaningful, and by default only compared, between routes learned from the same neighboring AS. Two routes with different origin ASes having different MED values isn’t a valid comparison at this step and most implementations won’t treat it as one by default. This default-scoped comparison is also the source of a genuinely well-known BGP gotcha: depending on the order routes are received in, the deterministic default comparison behavior can produce a different best path than a full pairwise comparison would, which is why bgp deterministic-med exists as a Cisco knob to force a stricter, order-independent comparison. It’s a good example of the algorithm having a documented, intentional default that still surprises people who haven’t read past the summary table.

7. Prefer eBGP over iBGP

All else equal, a route learned via an eBGP session is preferred over one learned via iBGP. This is a reasonable default: an eBGP-learned route generally represents a shorter, more direct path to the destination than one that’s already been relayed across the local AS’s own iBGP mesh.

8. Lowest IGP metric to the NEXT_HOP, and why that’s hot-potato routing by default

This step is where “hot potato” routing gets baked into the algorithm rather than existing as a separate design decision layered on top of it. Given two remaining candidate exit points from the AS, the router prefers whichever one is cheapest to reach according to its own IGP, which in practice means: get the traffic off this network and onto the next AS’s as quickly as possible, rather than carrying it further across infrastructure the local AS is paying for. That’s the default behavior every BGP speaker exhibits unless something further up this list already decided the outcome, and it’s directly opposed to “cold potato” routing, deliberately carrying traffic further on your own network before handing it off, which is a policy choice implemented by overriding earlier steps in this list, not a separate mechanism. Understanding step 8 as the origin of hot-potato behavior, rather than a vague industry term, is one of the places this algorithm stops being abstract and starts explaining actual traffic patterns on a real network.

9. Oldest route

Among eBGP-learned candidates still tied at this point, the longest-established route wins, a stability preference that avoids needlessly flapping the chosen best path every time a marginally newer, equally-good alternative shows up. This step is explicitly about eBGP paths; it doesn’t apply the same way to iBGP-learned candidates, which fall through to the router ID comparison below.

10. Lowest BGP Router ID (or ORIGINATOR_ID)

If a route has been through a route reflector, its ORIGINATOR_ID, from Part 3’s list of attributes deferred to Part 6, substitutes for the originating router’s ID in this comparison rather than the reflector’s own ID. Lowest value wins. This is functionally the same comparison RFC 4271’s own connection collision detection uses for a completely different purpose, deciding which of two colliding TCP sessions survives, which is a nice small reminder that BGP Identifier does real comparative work in more than one part of the protocol.

11. Shortest CLUSTER_LIST

Another attribute that only exists because of route reflection, covered fully in Part 6: among routes that have passed through one or more route reflectors, the one with the shortest CLUSTER_LIST, fewer reflection hops, is preferred.

12. Lowest neighbor IP address

The final tiebreak, and by this point genuinely a last resort: prefer the route learned from the peer with the numerically lowest IP address. Two different peers can’t share the same address, so this step is guaranteed to produce a single winner if everything above it has tied.

Multipath is a separate question

One thing worth naming explicitly: everything above answers “which single route is best.” Whether a router installs more than one equal-cost path into its forwarding table at all is a separate, vendor-specific multipath feature, and it only applies to routes that are genuinely tied through the steps that matter for equivalence (LOCAL_PREF, AS_PATH length, origin, and MED, typically) before multipath configuration decides whether to load-balance across them rather than picking one. It doesn’t change the algorithm above; it changes what happens once the algorithm produces a tied result that multipath is configured to accept rather than break with the remaining steps.

Part 5 moves from selection to propagation: the actual behavioral differences between eBGP and iBGP sessions, why AS_PATH loop prevention doesn’t do anything useful inside an AS, and why that gap is what makes iBGP’s full-mesh requirement unavoidable without the mechanisms Part 6 covers.