About ExternalService

Copy Markdown View Source

ExternalService is an Elixir library for safely calling external services and APIs, combining three well-established reliability techniques behind one small interface:

  • Retries for transient failures,
  • the Circuit Breaker pattern for persistent failures, and
  • rate limiting for staying within a service's quota.

Calls can be synchronous, asynchronous background tasks, or fanned out in parallel for MapReduce-style processing — all under the same retry, circuit breaker, and rate-limiting protection.

The ideas

Retrying failed requests

Many failures when accessing an external service are transient: network congestion causing a timeout, or a service briefly under heavy load. The best response is often simply to try again after a short backoff. ExternalService automates retry logic — linear or exponential backoff, jitter, delay caps, and both attempt-count and time budgets — using Safwan Kamarrudin's retry library. See Retries.

Circuit breakers

The Circuit Breaker pattern was first described in Michael Nygard's Release It! and later popularized by Martin Fowler. To quote Nygard, "Circuit breakers are a way to automatically degrade functionality when the system is under stress."

Like the electrical breakers they're named for, software circuit breakers protect a system from damage caused by a faulty component. By monitoring calls to an external service, a breaker can "trip" once failures cross a threshold, after which further calls fail fast instead of piling up against a service that is already in trouble. After a cool-down it resets and calls resume. Crucially, the breaker is global to the service, so a trip protects every caller at once and prevents cascading failures.

ExternalService implements circuit breakers on top of Jesper Louis Andersen's Erlang fuse library, managing the underlying fuse for you — you never call :fuse.ask or :fuse.melt yourself. See Circuit breakers.

Rate limiting

Many services impose a request quota. ExternalService can keep you under it automatically and application-wide, using ex_rated: excess calls sleep until the window allows them, rather than failing. See Rate limiting.

History

ExternalService grew out of production code at Ropig, where it was first used to make reliable calls to Google's Pub/Sub messaging service. It was one of author Jason Voegele's first open-source Elixir libraries and went on to see wide production adoption. The original overview is described in this blog post.

The 2.0 line is a ground-up modernization of that original library — validated and self-documenting options, telemetry, circuit-breaker introspection, structured errors, and a declarative module front door (use ExternalService) — while keeping the core idea unchanged: wrap a call in a function, hand it over, and let retries, the circuit breaker, and rate limiting just work.

License

ExternalService is released under the Apache 2.0 license.