Guide

BGP Best Path Selection: Weight, Local Preference, AS-Path

A BGP router often hears the same prefix from more than one neighbor. It keeps every path it accepts in its BGP table, marks exactly one as best, installs that one in the routing table and advertises only that one to its peers. The choice follows a fixed list of checks, and the first check where two paths differ decides. Three of those checks are the ones engineers set on purpose: weight, local preference and AS-path length. This guide works through all three on one four-router topology, with real IOS XE output at each step. Weight and local preference choose the exit your own traffic leaves by. AS-path prepending asks other networks to pick a different way back in. It assumes the sessions are already up; if they are not, start with How to Configure eBGP Peering.

eBGP at the edges, iBGP across the middle — the reference wiring for BGP, not a specific lab.

The order IOS XE compares paths in

A path must be usable before it is compared. Its next hop has to resolve through the routing table, and it must have passed inbound policy and loop checking (a path carrying your own AS number is dropped on arrival). An iBGP path with an unreachable next hop never competes, which is why iBGP designs rely on next-hop-self. No path exists at all until the session is Established; a session stuck in Idle or Active is a separate problem.

IOS XE then compares the usable paths step by step. The first step where they differ picks the winner, and nothing below it is consulted. Only weight and local preference prefer a higher value; every other step prefers the lower one. The three checks engineers set on purpose sit at steps 1, 2 and 4, ahead of almost everything else, and most steps below them only break ties.

RFC 4271 defines the standard decision process; weight is a Cisco addition. The order below follows Cisco's best-path reference, which also lists each step's exceptions.

  1. Highest weight. Cisco-specific and local to the router. Learned paths default to 0; paths the router originates get 32768.
  2. Highest local preference. Shared by every router in the AS; the default is 100.
  3. Locally originated. Paths this router created with network, redistribute or aggregate-address beat learned ones (the AIGP metric is also considered here where it is configured).
  4. Shortest AS path. This is the step prepending works on.
  5. Lowest origin code: IGP (i) before EGP (e) before incomplete (?).
  6. Lowest MED. By default it is compared only between paths from the same neighboring AS.
  7. eBGP over iBGP.
  8. Lowest IGP metric to the BGP next hop.
  9. Multipath check. If multipath is enabled, equal paths are installed together; the best path is still chosen by the steps below.
  10. If both paths are external, the one received first, which keeps the choice stable.
  11. Lowest router ID of the advertising router (the originator ID behind a route reflector).
  12. Shortest cluster list, which only exists behind route reflectors.
  13. Lowest neighbor address.

The lab: one prefix, two exits

R1 and R2 form AS 65001. They run OSPF area 0 on the 10.0.12.0/30 link between them and peer over iBGP between their Loopback0 addresses (10.255.0.1 and 10.255.0.2), with next-hop-self in both directions. R1 has an eBGP session to R3 in AS 65002 over 10.0.13.0/30. R2 has one to R4 in AS 65003 over 10.0.24.0/30. R3 and R4 also peer with each other over 10.0.34.0/30. No policy is applied yet.

R1 and R2 each originate a /24 from a loopback, 172.16.1.0/24 and 172.16.2.0/24, and R3 originates 198.51.100.0/24. R4 originates 203.0.113.0/24 and 192.0.2.0/24, so R1 hears each of those two prefixes twice: from R2 with AS path 65003, and from R3 with AS path 65002 65003. Weight and local preference tie at their defaults and neither path is local, so step 4 decides, and the path through R2 wins on the shorter AS path.

  • In the table below, *> marks the path R1 selected, and an i right after it means R1 learned that path over iBGP.
  • LocPrf is blank on paths learned from an eBGP neighbor. They still compete at the default of 100, which the detailed view prints for them.
  • Weight is 0 on every learned path. Only 172.16.1.0/24, which R1 originates itself, carries 32768.
  • In the detailed view, the Paths: line counts the candidates and numbers the winner (best #2 below). Each path shows its AS path, then its next hop and the neighbor it came from, then a status line ending in best for the winner.
R1# show ip bgp | begin Network
     Network          Next Hop            Metric LocPrf Weight Path
 *>   172.16.1.0/24    0.0.0.0                  0         32768 i
 *>i  172.16.2.0/24    10.255.0.2               0    100      0 i
 *    192.0.2.0        10.0.13.2                              0 65002 65003 i
 *>i                   10.255.0.2               0    100      0 65003 i
 *>   198.51.100.0     10.0.13.2                0             0 65002 i
 *    203.0.113.0      10.0.13.2                              0 65002 65003 i
 *>i                   10.255.0.2               0    100      0 65003 i

R1# show ip bgp 203.0.113.0/24
BGP routing table entry for 203.0.113.0/24, version 6
Paths: (2 available, best #2, table default)
  Flag: 0x8100
  Not advertised to any peer
  Refresh Epoch 1
  65002 65003
    10.0.13.2 from 10.0.13.2 (10.255.0.3)
      Origin IGP, localpref 100, valid, external
      rx pathid: 0, tx pathid: 0
      Updated on Sep 17 2026 17:11:29 UTC
  Refresh Epoch 1
  65003
    10.255.0.2 (metric 11) from 10.255.0.2 (10.255.0.2)
      Origin IGP, metric 0, localpref 100, valid, internal, best
      rx pathid: 0, tx pathid: 0x0
      Updated on Sep 17 2026 17:11:07 UTC

Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.

Weight: one router's private preference

Weight is not a BGP attribute. No update carries it, so no other router ever sees it. That makes it the right tool when one router needs a different exit from the rest of the AS, and the wrong one when the whole AS should move. Higher wins, and the range is 0 to 65535.

A weight on the neighbor applies to everything that neighbor sends; here R1 gives every path from R3 a weight of 200. Neighbor policy reaches routes already received only after a soft reset, which asks the neighbor to resend its routes without dropping the session.

R1(config)# router bgp 65001
R1(config-router)# neighbor 10.0.13.2 weight 200
R1(config-router)# end
R1# clear ip bgp 10.0.13.2 soft in

Verify: R1 moved, R2 did not

Every path from R3 now carries weight 200, so step 1 settles it: R1 prefers R3 for 203.0.113.0/24 and 192.0.2.0/24, although those paths are one AS longer. The traceroute confirms it. R3 answers first (10.0.13.2), then R4 on its R3-facing address (10.0.34.2). The asterisk in the last hop is IOS rate-limiting its unreachable replies, not packet loss.

Now look at what did not change. R1 still holds R2's path (next hop 10.255.0.2) for both prefixes, now marked * i instead of *>i. R2 is untouched, because the weight never left R1 and R2's own path through R4 is still one AS shorter than anything R1 can offer it. Replies come back through R2 too: R4 reaches 172.16.1.0/24 in one AS hop that way, and nothing R1 did changed that. Remove the weight and soft-reset again before the next step.

R1# show ip bgp | begin Network
     Network          Next Hop            Metric LocPrf Weight Path
 *>   172.16.1.0/24    0.0.0.0                  0         32768 i
 *>i  172.16.2.0/24    10.255.0.2               0    100      0 i
 *>   192.0.2.0        10.0.13.2                            200 65002 65003 i
 * i                   10.255.0.2               0    100      0 65003 i
 *>   198.51.100.0     10.0.13.2                0           200 65002 i
 *>   203.0.113.0      10.0.13.2                            200 65002 65003 i
 * i                   10.255.0.2               0    100      0 65003 i

R1# traceroute 203.0.113.1 source Loopback1 numeric
Type escape sequence to abort.
Tracing the route to 203.0.113.1
VRF info: (vrf in name/id, vrf out name/id)
  1 10.0.13.2 0 msec 1 msec 0 msec
  2 10.0.34.2 1 msec *  1 msec

Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.

Local preference: the exit the whole AS agrees on

Local preference is a real path attribute. A router usually sets it on routes arriving from an eBGP neighbor, then sends it to all its iBGP peers, so every router in the AS reaches the same answer at step 2. It is never sent to an eBGP neighbor. Higher wins, and the default is 100.

This policy is narrower than the weight above. R1 raises local preference to 200 only for 203.0.113.0/24 learned from R3. A prefix list selects the route, and a route-map sets the value. The empty permit 20 clause matters, as the trap below shows.

R1(config)# ip prefix-list AS65003-NETS seq 5 permit 203.0.113.0/24
R1(config)# route-map FROM-R3 permit 10
R1(config-route-map)# match ip address prefix-list AS65003-NETS
R1(config-route-map)# set local-preference 200
R1(config-route-map)# exit
R1(config)# route-map FROM-R3 permit 20
R1(config-route-map)# exit
R1(config)# router bgp 65001
R1(config-router)# neighbor 10.0.13.2 route-map FROM-R3 in
R1(config-router)# end
R1# clear ip bgp 10.0.13.2 soft in

Verify: the whole AS moved

R1 now holds a single path to 203.0.113.0/24: through R3, with localpref 200. The missing path from R2 is the proof that the policy spread. R1 advertised its new best path to R2 with local preference 200, and R2 preferred it to its own path through R4 at the default of 100. A router never passes an iBGP-learned path to another iBGP peer, so R2 withdrew its own advertisement. R2's own traffic for 203.0.113.0/24 therefore leaves through R1 and R3, with no configuration on R2.

The table shows the per-prefix control. 198.51.100.0/24 and 192.0.2.0/24 still arrive from R3 through the permit 20 clause with their attributes untouched, and 192.0.2.0/24 still leaves through R2 on the shorter AS path.

R1# show ip bgp 203.0.113.0/24
BGP routing table entry for 203.0.113.0/24, version 13
Paths: (1 available, best #1, table default)
  Advertised to update-groups:
     2         
  Refresh Epoch 5
  65002 65003
    10.0.13.2 from 10.0.13.2 (10.255.0.3)
      Origin IGP, localpref 200, valid, external, best
      rx pathid: 0, tx pathid: 0x0
      Updated on Sep 17 2026 17:13:59 UTC

R1# show ip bgp | begin Network
     Network          Next Hop            Metric LocPrf Weight Path
 *>   172.16.1.0/24    0.0.0.0                  0         32768 i
 *>i  172.16.2.0/24    10.255.0.2               0    100      0 i
 *    192.0.2.0        10.0.13.2                              0 65002 65003 i
 *>i                   10.255.0.2               0    100      0 65003 i
 *>   198.51.100.0     10.0.13.2                0             0 65002 i
 *>   203.0.113.0      10.0.13.2                     200      0 65002 65003 i

Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.

The trap: a route-map without a final permit

Every route-map ends in an implicit deny, and in BGP a denied route is simply not accepted. Apply the same policy without the permit 20 clause and R1 keeps exactly one of R3's three prefixes. Nothing goes down, which is what makes the fault easy to miss. R1 still reaches 198.51.100.0/24, but only the long way around through R2 and R4, because the path straight from its owner has been discarded.

show ip bgp neighbors 10.0.13.2 routes lists what survived R1's inbound policy; the prefix count at the end makes the missing routes obvious.

R1# show ip bgp 198.51.100.0/24
BGP routing table entry for 198.51.100.0/24, version 15
Paths: (1 available, best #1, table default)
  Flag: 0x8100
  Not advertised to any peer
  Refresh Epoch 1
  65003 65002
    10.255.0.2 (metric 11) from 10.255.0.2 (10.255.0.2)
      Origin IGP, metric 0, localpref 100, valid, internal, best
      rx pathid: 0, tx pathid: 0x0
      Updated on Sep 17 2026 17:14:33 UTC

R1# show ip bgp neighbors 10.0.13.2 routes
BGP table version is 15, local router ID is 10.255.0.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, 
              r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter, 
              x best-external, a additional-path, c RIB-compressed, 
              t secondary path, L long-lived-stale,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

     Network          Next Hop            Metric LocPrf Weight Path
 *>   203.0.113.0      10.0.13.2                     200      0 65002 65003 i

Total number of prefixes 1 

Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.

Weight or local preference?

Use local preference for policy the whole AS should follow, such as a primary and a backup provider. Use weight for a single-router exception, and remember that it overrides local preference on that router.

AttributeWeightLocal preference
Decision step12
Where it appliesOnly the router it is configured onEvery router in the AS
Sent in updatesNever; it is not a BGP attributeTo iBGP peers only, never to eBGP peers
Default0 for learned paths, 32768 for paths the router originates100
Preferred valueHighestHighest
Range0 to 655350 to 4294967295
Typical configurationPer neighbor, or per prefix in an inbound route-mapPer prefix in an inbound route-map
StandardCisco-specificWell-known attribute (RFC 4271)

AS-path prepending: steering traffic back in

Weight and local preference only decide how traffic leaves your AS. The way back is decided by routers in other networks, running the same algorithm on the routes you send them. You cannot set their weight or local preference, but you can change the next thing they compare: AS-path length.

Prepending repeats your own AS number on the routes you advertise to one neighbor, so the path through that neighbor looks longer. Here AS 65001 wants AS 65003 to send traffic in through R3 and R1 and keep the R2 to R4 link as a backup, so R2 adds 65001 twice on everything it sends R4. Four rules keep a prepend predictable.

  • Prepend only your own AS number. A path that carries another network's AS number is dropped by that network's routers as a loop.
  • Start with one or two repeats. Each extra copy counts only until the prepended path is longer than the alternative the neighbor holds; past that it changes nothing.
  • The neighbor's weight and local preference come first. Many providers set local preference by relationship, so their own policy can override your prepends.
  • When both links go to the same neighboring AS, a lower MED (step 6) is the more direct signal, because that neighbor compares MED between paths from one AS.
R2(config)# route-map PREPEND-TO-R4 permit 10
R2(config-route-map)# set as-path prepend 65001 65001
R2(config-route-map)# exit
R2(config)# router bgp 65001
R2(config-router)# neighbor 10.0.24.2 route-map PREPEND-TO-R4 out
R2(config-router)# end
R2# clear ip bgp 10.0.24.2 soft out

What R2's own view will not tell you

show route-map PREPEND-TO-R4 confirms the set clause is in place, but it says nothing about what R4 ended up with. Neither does show ip bgp neighbors 10.0.24.2 advertised-routes: it lists the three prefixes R2 sends R4, but the AS paths it prints carry none of the numbers the outbound route-map adds. Check the result where it lands, in R4's table, or on the internet through a looking glass in the other network.

R2# show route-map PREPEND-TO-R4
route-map PREPEND-TO-R4, permit, sequence 10
  Match clauses:
  Set clauses:
    as-path prepend 65001 65001
  Policy routing matches: 0 packets, 0 bytes

R2# show ip bgp neighbors 10.0.24.2 advertised-routes
BGP table version is 10, local router ID is 10.255.0.2
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, 
              r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter, 
              x best-external, a additional-path, c RIB-compressed, 
              t secondary path, L long-lived-stale,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

     Network          Next Hop            Metric LocPrf Weight Path
 *>i  172.16.1.0/24    10.255.0.1               0    100      0 i
 *>   172.16.2.0/24    0.0.0.0                  0         32768 i
 *>i  198.51.100.0     10.255.0.1               0    100      0 65002 i

Total number of prefixes 3 

Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.

Verify on the other side

R4 now holds 65001 65001 65001 through R2 and 65002 65001 through R3, and step 4 picks R3. The path through R2 carries 65001 three times: the two copies the route-map adds, plus the one R2 adds automatically as the update crosses the eBGP boundary. R4 is directly connected to R2, yet its traceroute to R2's own network now crosses R3 (10.0.34.1) and R1 (10.0.13.1) before reaching R2 (10.0.12.2).

The route-map has no match clause, so R2 prepends every route it sends R4, including 198.51.100.0/24, a route from AS 65002 that AS 65001 should not be offering at all. Stopping that transit leak is a separate job, covered in BGP prefix-list and AS-path filtering.

R4# show ip bgp | begin Network
     Network          Next Hop            Metric LocPrf Weight Path
 *>   172.16.1.0/24    10.0.34.1                              0 65002 65001 i
 *                     10.0.24.1                              0 65001 65001 65001 i
 *>   172.16.2.0/24    10.0.34.1                              0 65002 65001 i
 *                     10.0.24.1                0             0 65001 65001 65001 i
 *>   192.0.2.0        0.0.0.0                  0         32768 i
 *    198.51.100.0     10.0.24.1                              0 65001 65001 65001 65002 i
 *>                    10.0.34.1                0             0 65002 i
 *>   203.0.113.0      0.0.0.0                  0         32768 i

R4# traceroute 172.16.2.1 source Loopback1 numeric
Type escape sequence to abort.
Tracing the route to 172.16.2.1
VRF info: (vrf in name/id, vrf out name/id)
  1 10.0.34.1 0 msec 1 msec 0 msec
  2 10.0.13.1 0 msec 1 msec 0 msec
  3 10.0.12.2 0 msec *  4 msec

Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.

Your own exit does not change

Prepending changes only what R2 tells R4. R2 still sends its own traffic for 203.0.113.0/24 one hop straight to R4 at 10.0.24.2, so the two directions now take different paths. That is normal in BGP, and it is why a one-way traceroute never shows the whole picture.

R2# traceroute 203.0.113.1 source Loopback1 numeric
Type escape sequence to abort.
Tracing the route to 203.0.113.1
VRF info: (vrf in name/id, vrf out name/id)
  1 10.0.24.2 1 msec *  1 msec

Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.

When the path you set does not win

  • No soft reset. Policy reaches routes already exchanged only after clear ip bgp <neighbor> soft in or soft out; until then the table looks unchanged.
  • Wrong tool for the scope. Weight on R1 does nothing for R2. To move the whole AS, set local preference where the routes enter it.
  • An earlier step already decided. Any weight, including the 32768 on routes the router originates, outranks local preference, and local preference outranks AS-path length.
  • Routes vanished after adding a route-map. The implicit deny dropped every route no clause matched; show ip bgp neighbors <neighbor> routes shows what was kept.
  • The path is not a candidate. A path whose next hop cannot be resolved is marked (inaccessible) in the detailed show ip bgp output and never enters the comparison.
  • Checking the wrong router. Prepending and other outbound policy show their effect on the neighbor, not on the router that applies them.

Frequently asked questions

Is a higher or lower value better in BGP path selection?

It depends on the attribute. Weight and local preference prefer the highest value. AS-path length, origin code, MED, IGP metric to the next hop, router ID and neighbor address all prefer the lowest. The first attribute where two paths differ decides, so a higher weight wins even against a much shorter AS path.

Is BGP weight advertised to other routers?

No. Weight is a Cisco-specific value that exists only on the router where it is configured, and no BGP update carries it. To make every router in the autonomous system prefer the same exit, set local preference instead, which iBGP peers receive and compare.

Do I need to reset a BGP session after changing a route-map?

Not a hard reset. A new policy reaches routes already exchanged after a soft reset: clear ip bgp with the neighbor address and soft in for inbound policy, or soft out for outbound policy. The session stays up while the routes are sent again, so traffic keeps flowing.

Why is my AS-path prepending being ignored?

The neighboring network compares weight and local preference before AS-path length, so a policy it applies at either step overrides your prepends. Many providers set local preference by customer or peer relationship. Also check that you prepended on the backup link, used your own AS number, and soft-reset the session outbound.

What is the difference between MED and AS-path prepending?

Both ask other networks to prefer one way into yours. MED is a metric sent to a directly connected neighboring AS, lower is better, and by default it is compared only between paths from that same AS, so it suits two links to one provider. Prepending lengthens the AS path, which every network along the way sees, so it also works across links to different providers.

Labs to practice path selection

Set weight, local preference and prepends on real IOS, then get the config graded.

All BGP labs →

What grading looks like

This is what grading your config looks like

A sample result — 4 of 5 requirements met. This is exactly what you see the moment you submit.

bgp-lab-export.yaml — read 3 device configs

Score: 80% — Keep going (4 of 5 checks passed)

  • Passed: BGP process running as AS 65001 on R1
  • Passed: eBGP neighbor 10.0.13.2 in AS 65002
  • Passed: Session to 10.0.13.2 is Established
  • Passed: 172.16.1.0/24 originated by an exact match
  • Failed: next-hop-self toward the iBGP peer — missing on R2
Solution revealed

The full node-by-node answer key unlocks the moment you submit — so you see exactly what you missed.

Don't just read it — configure it

Reading is step one. Build BGP on real Cisco IOS and have your own config graded.