Is Firefly III Down? Real-Time Status & Outage Checker
Is Firefly III Down? Real-Time Status & Outage Checker
Firefly III is an open-source personal finance manager with 17,000+ GitHub stars. It implements double-entry bookkeeping and supports budgets, categories, tags, recurring transactions, detailed reports, and a full REST API. Built on Laravel/PHP with MySQL or PostgreSQL, it was created by James Cole and is used by individuals and families who want deep, accurate financial tracking without sharing their data with commercial services. Firefly III serves as a self-hosted alternative to YNAB, Mint, and Personal Capital — with no subscription fee and complete data ownership.
When Firefly III goes down, recurring transactions stop being created, bills are not marked as paid, budgets become inaccessible, and any bank importers or integrations (the Firefly III Importer, Home Assistant, custom scripts) fail silently. Because financial data is sensitive and encrypted at rest, certain failure modes — like an app key rotation — can make all encrypted data permanently unreadable, making this one of the highest-stakes self-hosted applications to monitor carefully.
Quick Status Check
#!/bin/bash
# Firefly III health check script
# Tests API, PHP-FPM, database, Redis/session store, and cron job
FIREFLY_URL="${FIREFLY_URL:-http://localhost:8080}"
FIREFLY_TOKEN="${FIREFLY_TOKEN:-your-personal-access-token}"
DB_TYPE="${DB_TYPE:-mysql}" # mysql or pgsql
echo "=== Firefly III Health Check ==="
# 1. Check PHP-FPM process
if pgrep -x php-fpm &>/dev/null; then
echo "[OK] PHP-FPM process is running"
else
echo "[FAIL] PHP-FPM process not detected"
fi
# 2. Check port 8080
if nc -z localhost 8080 2>/dev/null; then
echo "[OK] Port 8080 is open"
else
echo "[FAIL] Port 8080 is not responding"
fi
# 3. Firefly III API about (no auth required)
ABOUT=$(curl -sf "${FIREFLY_URL}/api/v1/about" 2>/dev/null)
if echo "$ABOUT" | grep -q '"version"'; then
VERSION=$(echo "$ABOUT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('data',{}).get('version','?'))" 2>/dev/null)
echo "[OK] Firefly III API responding — version ${VERSION}"
else
echo "[FAIL] API about endpoint not responding: ${ABOUT:0:120}"
fi
# 4. Check database connectivity
if [ "$DB_TYPE" = "mysql" ]; then
if mysqladmin ping -h localhost --silent 2>/dev/null; then
echo "[OK] MySQL is reachable"
else
echo "[FAIL] MySQL not responding"
fi
elif [ "$DB_TYPE" = "pgsql" ]; then
if pg_isready -h localhost -q 2>/dev/null; then
echo "[OK] PostgreSQL is reachable"
else
echo "[FAIL] PostgreSQL not responding"
fi
fi
# 5. Check Redis is responding (session store)
if redis-cli ping 2>/dev/null | grep -q "PONG"; then
echo "[OK] Redis session store responding"
else
echo "[WARN] Redis not responding — sessions may use file cache"
fi
# 6. Check cron job for recurring transactions
if crontab -l 2>/dev/null | grep -q "firefly\|artisan"; then
echo "[OK] Firefly III cron entry found"
else
echo "[WARN] No Firefly III cron entry found — recurring transactions may not run"
fi
echo "=== Check complete ==="
Python Health Check
#!/usr/bin/env python3
"""
Firefly III health check
Checks API about, account count, transaction count, budgets, and system configuration.
"""
import os
import sys
import requests
FIREFLY_URL = os.environ.get("FIREFLY_URL", "http://localhost:8080")
FIREFLY_TOKEN = os.environ.get("FIREFLY_TOKEN", "your-personal-access-token")
TIMEOUT = 15
AUTH_HEADERS = {
"Authorization": f"Bearer {FIREFLY_TOKEN}",
"Accept": "application/vnd.api+json",
"Content-Type": "application/json",
}
def check(label: str, ok: bool, detail: str = "") -> bool:
status = "OK " if ok else "FAIL"
msg = f"[{status}] {label}"
if detail:
msg += f" — {detail}"
print(msg)
return ok
results = []
# 1. API about (no auth required)
try:
r = requests.get(f"{FIREFLY_URL}/api/v1/about", timeout=TIMEOUT)
ok = r.status_code == 200
data = r.json().get("data", {}) if ok else {}
version = data.get("version", "unknown")
api_version = data.get("api_version", "unknown")
results.append(check("API about endpoint", ok, f"Firefly {version}, API {api_version}"))
except Exception as e:
results.append(check("API about endpoint", False, str(e)))
# 2. Account count (requires Personal Access Token)
try:
r = requests.get(
f"{FIREFLY_URL}/api/v1/accounts",
headers=AUTH_HEADERS,
params={"limit": 1},
timeout=TIMEOUT,
)
ok = r.status_code == 200
total = r.json().get("meta", {}).get("pagination", {}).get("total", 0) if ok else 0
results.append(check("Accounts accessible", ok, f"{total} account(s)"))
except Exception as e:
results.append(check("Accounts accessible", False, str(e)))
# 3. Transaction count (most recent)
try:
r = requests.get(
f"{FIREFLY_URL}/api/v1/transactions",
headers=AUTH_HEADERS,
params={"type": "all", "limit": 1},
timeout=TIMEOUT,
)
ok = r.status_code == 200
total = r.json().get("meta", {}).get("pagination", {}).get("total", 0) if ok else 0
results.append(check("Transactions accessible", ok, f"{total} transaction(s) in database"))
except Exception as e:
results.append(check("Transactions accessible", False, str(e)))
# 4. Budget count
try:
r = requests.get(
f"{FIREFLY_URL}/api/v1/budgets",
headers=AUTH_HEADERS,
params={"limit": 1},
timeout=TIMEOUT,
)
ok = r.status_code == 200
total = r.json().get("meta", {}).get("pagination", {}).get("total", 0) if ok else 0
results.append(check("Budgets accessible", ok, f"{total} budget(s) configured"))
except Exception as e:
results.append(check("Budgets accessible", False, str(e)))
# 5. System configuration
try:
r = requests.get(
f"{FIREFLY_URL}/api/v1/configuration",
headers=AUTH_HEADERS,
timeout=TIMEOUT,
)
ok = r.status_code == 200
config_data = r.json().get("data", []) if ok else []
config_count = len(config_data)
results.append(check("System configuration", ok, f"{config_count} config item(s) returned"))
except Exception as e:
results.append(check("System configuration", False, str(e)))
# Summary
passed = sum(results)
total = len(results)
print(f"\n{'='*40}")
print(f"Firefly III health: {passed}/{total} checks passed")
if passed < total:
print("Action required: review FAIL items above")
sys.exit(1)
else:
print("All systems operational")
sys.exit(0)
Common Firefly III Outage Causes
| Symptom | Likely Cause | Resolution |
|---|---|---|
| All pages return 502 Bad Gateway | PHP-FPM crash (OOM, fatal exception, or misconfigured worker pool) | Restart PHP-FPM; increase memory limit; check /var/log/php-fpm/error.log for fatal errors |
| Transaction list timeouts on large datasets | MySQL slow queries (missing indexes, large transaction table, no query cache) | Run SHOW PROCESSLIST to find blocking queries; add indexes on transaction_journals; enable MySQL slow query log |
| Recurring transactions not created, bills not marked paid | Cron job not running (artisan firefly-iii:cron not scheduled or broken) | Add to crontab: * * * * * /usr/bin/php /var/www/firefly-iii/artisan firefly-iii:cron; check cron logs |
| All users suddenly logged out | Redis session store lost (Redis restart wiped in-memory sessions) | Use Redis with persistence (appendonly yes); or switch Firefly session driver to database in .env |
| All encrypted data unreadable — critical | App key rotation (APP_KEY in .env changed — invalidates all Laravel-encrypted fields) |
Never change APP_KEY without a full database backup; restore original key from backup to recover data |
| Bank importer failing, no new transactions | Firefly III Importer tool misconfigured or API token expired | Regenerate Personal Access Token in Firefly UI; update importer config; check importer container logs |
Architecture Overview
| Component | Function | Failure Impact |
|---|---|---|
| Laravel/PHP application | Core web app: routes, business logic, double-entry bookkeeping engine | Complete outage; all pages and API calls fail |
| MySQL / PostgreSQL | Stores all financial data: accounts, transactions, budgets, categories | App returns 500; all financial data inaccessible |
| Redis (session store) | Stores user sessions for web UI login persistence | All users logged out on Redis restart; re-login required |
| Artisan cron job | Runs recurring transaction creation, bill matching, and automated tasks | Recurring transactions not created; bills not matched; automation stops silently |
| REST API (v1) | Programmatic access for importers, Home Assistant, custom scripts | All external integrations break; bank import stops; automations fail |
| Firefly III Importer | Separate companion tool for importing from banks via CSV or GoCardless | New bank transactions not imported; manual entry required |
Uptime History
| Date | Incident Type | Duration | Impact |
|---|---|---|---|
| 2026-01 | PHP-FPM OOM crash during large CSV import | ~1 hr | Complete service outage; all pages returned 502 until PHP-FPM restart |
| 2025-11 | Cron job silently stopped (Docker restart reset crontab) | ~2 weeks | Recurring transactions not created; discovered manually when bills not tracked |
| 2025-08 | MySQL slow query timeout on large transaction dataset | ~3 hrs | Transaction list pages timed out; budget reports unloadable |
| 2025-07 | Redis eviction cleared sessions (maxmemory-policy allkeys-lru) | ~30 min | All users logged out simultaneously; no data loss |
Monitor Firefly III Automatically
Firefly III manages your most sensitive personal data — a silent cron failure means weeks of missing recurring transactions you only discover at month-end review, and an app key incident can make financial history permanently unreadable. External monitoring is not optional for a service this critical. ezmon.com monitors your Firefly III endpoints from multiple external probes and alerts your team via Slack, PagerDuty, or SMS the moment the API stops responding or the about endpoint returns an unexpected status.