Two days ago, a magnitude 6.3 earthquake struck 84 miles south of Nikolski, Alaska. I found out about it 40 minutes later scrolling through Twitter. Forty minutes.
That bugged me. There's free, real-time seismic data sitting right there — why wasn't I checking it myself? So I spent an evening building a 30-line Python script that now runs in my terminal every morning. Here's exactly how it works.
The Data Source
The USGS publishes earthquake data as a free GeoJSON feed. No API key, no registration, no rate limit headaches. You get everything from M1.0 microquakes to M8.0+ megathrust events, updated within minutes of occurrence.
The feed gives you:
- Magnitude and magnitude type (ml, mb, mw)
- Exact coordinates and depth
- Timestamp (UTC)
- Location description (human-readable)
- Felt reports (how many people reported feeling it)
- Alert level (PAGER: green/yellow/orange/red)
The Script
Install one dependency:
pip install rich
Then save this as quake_check.py:
import requests
from rich.console import Console
from rich.table import Table
from rich.text import Text
from datetime import datetime
console = Console()
def get_earthquakes(min_mag=4.5, limit=20):
"""Fetch recent earthquakes from the USGS feed."""
url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/significant_week.geojson"
resp = requests.get(url, timeout=10)
resp.raise_for_status()
return resp.json()["features"][:limit]
def mag_color(mag):
if mag >= 6.0: return "bold red"
if mag >= 5.0: return "red"
if mag >= 4.0: return "yellow"
return "green"
def show_quakes(features):
table = Table(title="Recent Significant Earthquakes", show_lines=True)
table.add_column("Mag", justify="center", style="bold")
table.add_column("Location")
table.add_column("Depth")
table.add_column("Time (UTC)")
table.add_column("Reports")
for eq in features:
p = eq["properties"]
coords = eq["geometry"]["coordinates"]
t = datetime.utcfromtimestamp(p["time"] / 1000).strftime("%Y-%m-%d %H:%M")
style = mag_color(p["mag"])
table.add_row(
Text(f"{p['mag']:.1f}", style=style),
p["place"] or "Unknown",
f"{coords[2]:.0f} km",
t,
str(p.get("felt") or "-"),
)
console.print(table)
if __name__ == "__main__":
quakes = get_earthquakes()
show_quakes(quakes)
console.print(f"\n[dim]Source: USGS Earthquake Hazards Program[/dim]")
Run it:
python3 quake_check.py
That's it. You'll see something like this in your terminal:
Recent Significant Earthquakes
┌───────┬──────────────────────────────────┬────────┬──────────────────┬─────────┐
│ Mag │ Location │ Depth │ Time (UTC) │ Reports │
├───────┼──────────────────────────────────┼────────┼──────────────────┼─────────┤
│ 6.3 │ 84 km SSW of Nikolski, Alaska │ 35 km │ 2026-09-03 14:22 │ 47 │
│ 5.4 │ 21 km WNW of Jiangyou, China │ 10 km │ 2026-09-02 08:15 │ 112 │
│ 5.1 │ 69 km E of Antofagasta, Argentina│ 124 km │ 2026-09-01 22:07 │ - │
│ 5.5 │ 168 km ESE of Kuril'sk, Russia │ 55 km │ 2026-08-31 19:44 │ - │
│ 5.0 │ Pagar Alam, Indonesia │ 22 km │ 2026-08-31 16:33 │ 8 │
└───────┴──────────────────────────────────┴────────┴──────────────────┴─────────┘
Making It More Useful
The script above shows only "significant" events. Here's how to filter by your own criteria:
Filter by magnitude
Change the feed URL to get all M2.5+ earthquakes from the past week:
url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_week.geojson"
Different feed options:
| Feed | What you get |
|---|---|
significant_week |
Only significant events |
4.5_week |
M4.5+ past 7 days |
2.5_week |
M2.5+ past 7 days |
all_hour |
Everything in the last hour |
Filter by distance from your city
from math import radians, sin, cos, sqrt, atan2
def haversine(lat1, lon1, lat2, lon2):
"""Distance in km between two coordinates."""
R = 6371
dlat = radians(lat2 - lat1)
dlon = radians(lon2 - lon1)
a = sin(dlat/2)**2 + cos(radians(lat1)) * cos(radians(lat2)) * sin(dlon/2)**2
return R * 2 * atan2(sqrt(a), sqrt(1-a))
def near_me(features, my_lat, my_lon, max_km=500):
"""Only earthquakes within max_km of my location."""
return [
eq for eq in features
if haversine(my_lat, my_lon, eq["geometry"]["coordinates"][1],
eq["geometry"]["coordinates"][0]) <= max_km
]
Call it with your coordinates:
# San Francisco: 37.77, -122.42
# Tokyo: 35.68, 139.69
# Mexico City: 19.43, -99.13
nearby = near_me(quakes, my_lat=37.77, my_lon=-122.42, max_km=300)
Add desktop notifications (optional)
import subprocess
def notify(title, message):
"""Send a desktop notification (Linux/macOS)."""
subprocess.run(["notify-send", title, message])
Hook it into the main loop:
for eq in quakes:
if eq["properties"]["mag"] >= 5.0:
p = eq["properties"]
notify(f"M{p['mag']} Earthquake!", p["place"])
What I Actually Learned
A few things surprised me building this:
There are ~250 earthquakes per day worldwide. Most are tiny and nobody feels them. But M2.5+? Still about 60-70 per day. The earth is constantly moving.
Depth matters more than you'd think. A M5.0 at 10 km depth causes way more damage than a M6.0 at 400 km depth. The script shows depth for a reason.
The USGS feed is fast. Events typically appear within 5-10 minutes of occurrence. That's fast enough for personal monitoring, though not for early warning systems (those need seismometer networks).
Alaska accounts for ~50% of US earthquakes. Looking at the data, it's kind of wild how much seismic activity happens up there versus the contiguous US.
Auto-Running It
Want it to check every hour? Add a cron job:
# Check every hour, save to file
0 * * * * /usr/bin/python3 /path/to/quake_check.py >> /tmp/quakes.log 2>&1
Or run it as a background loop:
import time
while True:
quakes = get_earthquakes()
show_quakes(quakes)
console.print(f"\n[dim]Checking again in 30 minutes...[/dim]")
time.sleep(1800)
Wrapping Up
Total lines of code: 30. Total cost: $0. Total setup time: 5 minutes.
This is one of those projects where the effort-to-value ratio is absurdly good. You get real-time earthquake monitoring for any location on Earth, with no API keys and no dependencies beyond rich.
If you're building something that needs earthquake data as part of a larger project — weather dashboards, disaster preparedness tools, IoT safety systems — I've been using QuotaLink which bundles several free data APIs (earthquake, weather, air quality) into a single endpoint. Could save you some glue code.
Resources:
- USGS Earthquake Feeds — All available GeoJSON feeds
- USGS Earthquake API Docs — For custom queries beyond the feeds
- Rich Library — Beautiful terminal output in Python
Top comments (0)