Troubleshooting

Common issues and practical workarounds.

Hot-Reload and Branch Switching

If you enable watch on all services and frequently switch branches, pull, or merge, fuku will detect hundreds of file changes at once. Even with debouncing, this can cause a cascade of restarts and readiness check timeouts.

Recommended workflow

  • Only watch services you actively modify. There's no need to watch services you're not changing. Add watch to 3-5 services, not all of them.
  • Stop fuku before git operations. Before pulling, merging, rebasing, or switching branches, stop fuku first. Start it again after the operation completes.
  • Use profiles to limit scope. If you're working on the payment flow, run fuku run payments instead of starting all 50 services.

Readiness Check Timeouts

If a service fails readiness checks, fuku retries up to the configured limit and then marks it as failed. Common causes:

  • Wrong port or URL. Double-check the address or url in your readiness config matches what the service actually listens on.
  • Service starts slowly. Increase the timeout value. Some services (especially Java or Ruby) need more than the default 30 seconds on first start.
  • Database not ready. If a service depends on a database that's started externally, make sure it's running before starting fuku.
  • Port conflict. Another process may already be listening on the same port. Check with lsof -i :PORT.
fuku.yaml
services:
  slow-service:
    dir: slow-service
    tier: core
    readiness:
      type: http
      url: "http://localhost:8080/health"
      timeout: "60s" # Give it more time
      interval: "1s" # Check less frequently

Orphaned Processes

If fuku is killed abruptly (e.g., kill -9, terminal crash), child processes may keep running. You can clean them up with:

terminal
# Stop all services managed by fuku
fuku stop

# Or find processes manually by port
lsof -i :3000

fuku also runs a preflight cleanup automatically on next start, killing orphaned processes in service directories.


Port Conflicts

If a service fails to start with "address already in use", another process is occupying the port. This often happens after an unclean shutdown.

terminal
# Find what's using port 8000
lsof -i :8000

# Kill it
kill $(lsof -t -i :8000)

Starting fuku again will run preflight cleanup automatically, which handles most orphaned processes.


High CPU from File Watching

Watching large directories (e.g., node_modules, vendor) causes high CPU usage from filesystem event processing. Make sure your ignore patterns exclude these:

fuku.yaml
x-watch: &watch
  include:
    - "**/*.go"
  ignore:
    - ".git/**"
    - "vendor/**"
    - "node_modules/**"
    - "tmp/**"
    - "log/**"
    - "**/*_test.go"
    - "**/*_mock.go"
  debounce: 1s

Services Starting in Wrong Order

If a service tries to connect to a dependency that isn't ready yet, check your tier configuration. Services in earlier tiers start first and must pass readiness checks before the next tier begins.

  • Make sure dependencies are in an earlier tier than the services that need them.
  • Add readiness checks to dependencies so fuku waits until they're actually accepting connections, not just started.
  • Without readiness checks, fuku only waits for the process to start — which doesn't mean the service is ready.

Log Output is Noisy

When running many services, interleaved logs can be hard to read. Options:

  • Use the TUI. The interactive dashboard lets you filter logs by service.
  • Use fuku logs in a separate terminal to stream logs from specific services:
terminal
# Stream logs from specific services only
fuku logs api auth
  • Limit log output per service. Some services are noisier than others. You can restrict which streams are captured:
fuku.yaml
services:
  noisy-service:
    dir: noisy-service
    logs:
      output: [stderr] # Only capture stderr, skip stdout