Skip to content

Useful Queries

This section provides ready-to-use SQL queries for common BGP monitoring and analysis tasks. All queries are designed to work with TimescaleDB and take advantage of the hypertable structure for optimal performance.

Route Analysis Queries

Routes with High Churn (Most Unstable Routes)

Identify routes that change frequently, indicating potential instability:

SELECT
    prefix,
    router_ip,
    peer_ip,
    times_changed,
    total_announcements,
    total_withdrawals,
    last_updated,
    (total_announcements + total_withdrawals) as total_activity
FROM route_history
WHERE current_state = 'active'
    AND times_changed > 10
ORDER BY times_changed DESC, total_activity DESC
LIMIT 50;

Oldest Active Routes

Find the longest-lived routes in the routing table:

SELECT
    prefix,
    router_ip,
    peer_ip,
    first_seen,
    last_updated,
    AGE(NOW(), first_seen) as route_age,
    times_changed,
    family
FROM route_history
WHERE current_state = 'active'
ORDER BY first_seen ASC
LIMIT 50;

Newest Routes (Recent Announcements)

Identify recently announced routes:

SELECT
    prefix,
    router_ip,
    peer_ip,
    next_hop,
    as_path,
    first_seen,
    family
FROM route_history
WHERE current_state = 'active'
    AND first_seen >= NOW() - INTERVAL '24 hours'
ORDER BY first_seen DESC
LIMIT 100;

Route Churn Over Time

Analyze route instability trends over the past week:

SELECT
    time_bucket('1 hour', time) as hour,
    COUNT(*) as total_updates,
    COUNT(DISTINCT prefix) as unique_prefixes,
    SUM(CASE WHEN is_withdrawn THEN 1 ELSE 0 END) as withdrawals,
    SUM(CASE WHEN NOT is_withdrawn THEN 1 ELSE 0 END) as announcements,
    family
FROM routes
WHERE time >= NOW() - INTERVAL '7 days'
GROUP BY hour, family
ORDER BY hour DESC;

EVPN Specific Queries

Find MAC Address in EVPN Type 2 Routes

Search for a specific MAC address across all EVPN Type 2 routes:

SELECT
    prefix,
    router_ip,
    peer_ip,
    mac_address,
    ip_address,
    route_distinguisher,
    esi,
    ethernet_tag_id,
    mpls_label1,
    mpls_label2,
    time,
    is_withdrawn
FROM routes
WHERE family = 'EVPN'
    AND route_type = 'MAC/IP Advertisement'
    AND mac_address = '00:50:56:9c:69:b6'  -- Replace with target MAC
ORDER BY time DESC;

EVPN Route Types Distribution

Get an overview of EVPN route type distribution:

SELECT
    route_type,
    COUNT(*) as route_count,
    COUNT(DISTINCT router_ip) as router_count,
    COUNT(DISTINCT route_distinguisher) as rd_count
FROM routes
WHERE family = 'EVPN'
    AND is_withdrawn = false
    AND time >= NOW() - INTERVAL '24 hours'
GROUP BY route_type
ORDER BY route_count DESC;

EVPN ESI (Ethernet Segment) Analysis

Analyze Ethernet Segment activity:

SELECT
    esi,
    route_distinguisher,
    COUNT(*) as route_count,
    COUNT(DISTINCT mac_address) as unique_macs,
    COUNT(DISTINCT ip_address) as unique_ips,
    MIN(time) as first_seen,
    MAX(time) as last_seen
FROM routes
WHERE family = 'EVPN'
    AND esi IS NOT NULL
    AND esi != '00:00:00:00:00:00:00:00:00:00'
    AND is_withdrawn = false
GROUP BY esi, route_distinguisher
ORDER BY route_count DESC;

Router and Peer Analysis

Active Router Sessions

Monitor currently active router sessions:

SELECT
    router_ip,
    router_name,
    session_start,
    AGE(NOW(), session_start) as session_duration,
    peer_as,
    peer_bgp_id,
    total_messages,
    status
FROM router_sessions
WHERE status = 'active'
ORDER BY session_start ASC;

Peer Statistics (Last 24 Hours)

Analyze peer activity and message counts:

SELECT
    router_ip,
    peer_ip,
    peer_as,
    COUNT(*) as total_updates,
    COUNT(DISTINCT prefix) as unique_prefixes,
    SUM(CASE WHEN is_withdrawn THEN 1 ELSE 0 END) as withdrawals,
    SUM(CASE WHEN NOT is_withdrawn THEN 1 ELSE 0 END) as announcements,
    family
FROM routes
WHERE time >= NOW() - INTERVAL '24 hours'
GROUP BY router_ip, peer_ip, peer_as, family
ORDER BY total_updates DESC;

Router Message Volume

Monitor message processing volume per router:

SELECT
    router_ip,
    COUNT(*) as total_messages,
    COUNT(CASE WHEN family = 'IPv4' THEN 1 END) as ipv4_messages,
    COUNT(CASE WHEN family = 'IPv6' THEN 1 END) as ipv6_messages,
    COUNT(CASE WHEN family = 'EVPN' THEN 1 END) as evpn_messages,
    MIN(time) as first_message,
    MAX(time) as last_message
FROM routes
WHERE time >= NOW() - INTERVAL '24 hours'
GROUP BY router_ip
ORDER BY total_messages DESC;

AS Path Analysis

Most Common AS Paths

Identify the most frequently seen AS paths:

SELECT
    as_path,
    COUNT(*) as occurrence_count,
    COUNT(DISTINCT prefix) as unique_prefixes,
    COUNT(DISTINCT router_ip) as router_count
FROM routes
WHERE time >= NOW() - INTERVAL '24 hours'
    AND is_withdrawn = false
    AND as_path IS NOT NULL
GROUP BY as_path
ORDER BY occurrence_count DESC
LIMIT 50;

Routes by Origin AS

Analyze routes by their origin AS (last AS in path):

SELECT
    RIGHT(TRIM(as_path), POSITION(' ' IN REVERSE(TRIM(as_path) || ' ')) - 1) as origin_as,
    COUNT(*) as route_count,
    COUNT(DISTINCT prefix) as unique_prefixes
FROM routes
WHERE time >= NOW() - INTERVAL '24 hours'
    AND is_withdrawn = false
    AND as_path IS NOT NULL
    AND family = 'IPv4'
GROUP BY origin_as
ORDER BY route_count DESC
LIMIT 30;

Prefix Analysis

Largest Prefixes (Most Specific)

Find the most specific prefixes in the routing table:

SELECT
    prefix,
    prefix_len,
    router_ip,
    peer_ip,
    next_hop,
    as_path,
    time,
    family
FROM routes
WHERE is_withdrawn = false
    AND time >= NOW() - INTERVAL '24 hours'
ORDER BY prefix_len DESC, family, prefix
LIMIT 100;

Prefix Length Distribution

Analyze the distribution of prefix lengths:

SELECT
    prefix_len,
    family,
    COUNT(*) as route_count,
    COUNT(DISTINCT prefix) as unique_prefixes,
    COUNT(DISTINCT router_ip) as router_count
FROM routes
WHERE is_withdrawn = false
    AND time >= NOW() - INTERVAL '24 hours'
GROUP BY prefix_len, family
ORDER BY family, prefix_len;

Performance and Statistics

Hourly Route Statistics (Pre-computed)

Use the continuous aggregate for fast hourly statistics:

SELECT
    hour,
    router_ip,
    peer_ip,
    family,
    total_updates,
    unique_prefixes,
    withdrawals,
    announcements,
    (announcements - withdrawals) as net_announcements
FROM hourly_route_stats
WHERE hour >= NOW() - INTERVAL '7 days'
ORDER BY hour DESC, total_updates DESC;

Database Size and Growth

Monitor table sizes and growth:

SELECT
    schemaname,
    tablename,
    pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) as size,
    pg_total_relation_size(schemaname||'.'||tablename) as size_bytes
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;

Advanced Monitoring Queries

Route Leak Detection

Detect potential route leaks (routes with unusually long AS paths):

SELECT
    prefix,
    router_ip,
    peer_ip,
    as_path,
    array_length(string_to_array(as_path, ' '), 1) as path_length,
    time,
    family
FROM routes
WHERE is_withdrawn = false
    AND time >= NOW() - INTERVAL '24 hours'
    AND as_path IS NOT NULL
    AND array_length(string_to_array(as_path, ' '), 1) > 10  -- Adjust threshold
ORDER BY path_length DESC
LIMIT 50;

Rapid Route Changes (Flapping Detection)

Identify routes that are changing very frequently (potential flapping):

SELECT
    prefix,
    router_ip,
    peer_ip,
    COUNT(*) as changes_last_hour,
    array_agg(DISTINCT is_withdrawn) as change_types,
    MIN(time) as first_change,
    MAX(time) as last_change
FROM routes
WHERE time >= NOW() - INTERVAL '1 hour'
GROUP BY prefix, router_ip, peer_ip
HAVING COUNT(*) > 5  -- More than 5 changes in an hour
ORDER BY changes_last_hour DESC;

Next-hop Analysis

Analyze next-hop diversity and changes:

SELECT
    next_hop,
    COUNT(*) as route_count,
    COUNT(DISTINCT prefix) as unique_prefixes,
    COUNT(DISTINCT router_ip) as router_count,
    family
FROM routes
WHERE is_withdrawn = false
    AND time >= NOW() - INTERVAL '24 hours'
    AND next_hop IS NOT NULL
GROUP BY next_hop, family
ORDER BY route_count DESC
LIMIT 50;

Query Performance Tips

Performance Optimization

  • Always include time constraints in your queries to leverage TimescaleDB's time-partitioning
  • Use the hourly_route_stats materialized view for aggregated data analysis
  • Add appropriate indexes for frequently queried columns
  • Consider using time_bucket() for time-series aggregations

Query Customization

  • Replace time intervals (INTERVAL '24 hours') with your desired timeframe
  • Adjust thresholds and limits based on your network size and requirements
  • Use specific router IPs or peer IPs to focus on particular network segments