Skip to main content

An extremely fast Python linter and code formatter, written in Rust.

Project description

Ruff

Ruff image image image Actions status Discord

Docs | Playground

An extremely fast Python linter and code formatter, written in Rust.

Shows a bar chart with benchmark results.

Linting the CPython codebase from scratch.

  • ⚡️ 10-100x faster than existing linters (like Flake8) and formatters (like Black)
  • 🐍 Installable via pip
  • 🛠️ pyproject.toml support
  • 🤝 Python 3.13 compatibility
  • ⚖️ Drop-in parity with Flake8, isort, and Black
  • 📦 Built-in caching, to avoid re-analyzing unchanged files
  • 🔧 Fix support, for automatic error correction (e.g., automatically remove unused imports)
  • 📏 Over 800 built-in rules, with native re-implementations of popular Flake8 plugins, like flake8-bugbear
  • ⌨️ First-party editor integrations for VS Code and more
  • 🌎 Monorepo-friendly, with hierarchical and cascading configuration

Ruff aims to be orders of magnitude faster than alternative tools while integrating more functionality behind a single, common interface.

Ruff can be used to replace Flake8 (plus dozens of plugins), Black, isort, pydocstyle, pyupgrade, autoflake, and more, all while executing tens or hundreds of times faster than any individual tool.

Ruff is extremely actively developed and used in major open-source projects like:

...and many more.

Ruff is backed by Astral. Read the launch post, or the original project announcement.

Testimonials

Sebastián Ramírez, creator of FastAPI:

Ruff is so fast that sometimes I add an intentional bug in the code just to confirm it's actually running and checking the code.

Nick Schrock, founder of Elementl, co-creator of GraphQL:

Why is Ruff a gamechanger? Primarily because it is nearly 1000x faster. Literally. Not a typo. On our largest module (dagster itself, 250k LOC) pylint takes about 2.5 minutes, parallelized across 4 cores on my M1. Running ruff against our entire codebase takes .4 seconds.

Bryan Van de Ven, co-creator of Bokeh, original author of Conda:

Ruff is ~150-200x faster than flake8 on my machine, scanning the whole repo takes ~0.2s instead of ~20s. This is an enormous quality of life improvement for local dev. It's fast enough that I added it as an actual commit hook, which is terrific.

Timothy Crosley, creator of isort:

Just switched my first project to Ruff. Only one downside so far: it's so fast I couldn't believe it was working till I intentionally introduced some errors.

Tim Abbott, lead developer of Zulip:

This is just ridiculously fast... ruff is amazing.

Table of Contents

For more, see the documentation.

  1. Getting Started
  2. Configuration
  3. Rules
  4. Contributing
  5. Support
  6. Acknowledgements
  7. Who's Using Ruff?
  8. License

Getting Started

For more, see the documentation.

Installation

Ruff is available as ruff on PyPI.

Invoke Ruff directly with uvx:

uvx ruff check   # Lint all files in the current directory.
uvx ruff format  # Format all files in the current directory.

Or install Ruff with uv (recommended), pip, or pipx:

# With uv.
uv tool install ruff@latest  # Install Ruff globally.
uv add --dev ruff            # Or add Ruff to your project.

# With pip.
pip install ruff

# With pipx.
pipx install ruff

Starting with version 0.5.0, Ruff can be installed with our standalone installers:

# On macOS and Linux.
curl -LsSf https://astral.sh/ruff/install.sh | sh

# On Windows.
powershell -c "irm https://astral.sh/ruff/install.ps1 | iex"

# For a specific version.
curl -LsSf https://astral.sh/ruff/0.11.11/install.sh | sh
powershell -c "irm https://astral.sh/ruff/0.11.11/install.ps1 | iex"

You can also install Ruff via Homebrew, Conda, and with a variety of other package managers.

Usage

To run Ruff as a linter, try any of the following:

ruff check                          # Lint all files in the current directory (and any subdirectories).
ruff check path/to/code/            # Lint all files in `/path/to/code` (and any subdirectories).
ruff check path/to/code/*.py        # Lint all `.py` files in `/path/to/code`.
ruff check path/to/code/to/file.py  # Lint `file.py`.
ruff check @arguments.txt           # Lint using an input file, treating its contents as newline-delimited command-line arguments.

Or, to run Ruff as a formatter:

ruff format                          # Format all files in the current directory (and any subdirectories).
ruff format path/to/code/            # Format all files in `/path/to/code` (and any subdirectories).
ruff format path/to/code/*.py        # Format all `.py` files in `/path/to/code`.
ruff format path/to/code/to/file.py  # Format `file.py`.
ruff format @arguments.txt           # Format using an input file, treating its contents as newline-delimited command-line arguments.

Ruff can also be used as a pre-commit hook via ruff-pre-commit:

- repo: https://github.com/astral-sh/ruff-pre-commit
  # Ruff version.
  rev: v0.11.11
  hooks:
    # Run the linter.
    - id: ruff
      args: [ --fix ]
    # Run the formatter.
    - id: ruff-format

Ruff can also be used as a VS Code extension or with various other editors.

Ruff can also be used as a GitHub Action via ruff-action:

name: Ruff
on: [ push, pull_request ]
jobs:
  ruff:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/ruff-action@v3

Configuration

Ruff can be configured through a pyproject.toml, ruff.toml, or .ruff.toml file (see: Configuration, or Settings for a complete list of all configuration options).

If left unspecified, Ruff's default configuration is equivalent to the following ruff.toml file:

# Exclude a variety of commonly ignored directories.
exclude = [
    ".bzr",
    ".direnv",
    ".eggs",
    ".git",
    ".git-rewrite",
    ".hg",
    ".ipynb_checkpoints",
    ".mypy_cache",
    ".nox",
    ".pants.d",
    ".pyenv",
    ".pytest_cache",
    ".pytype",
    ".ruff_cache",
    ".svn",
    ".tox",
    ".venv",
    ".vscode",
    "__pypackages__",
    "_build",
    "buck-out",
    "build",
    "dist",
    "node_modules",
    "site-packages",
    "venv",
]

# Same as Black.
line-length = 88
indent-width = 4

# Assume Python 3.9
target-version = "py39"

[lint]
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
select = ["E4", "E7", "E9", "F"]
ignore = []

# Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"]
unfixable = []

# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[format]
# Like Black, use double quotes for strings.
quote-style = "double"

# Like Black, indent with spaces, rather than tabs.
indent-style = "space"

# Like Black, respect magic trailing commas.
skip-magic-trailing-comma = false

# Like Black, automatically detect the appropriate line ending.
line-ending = "auto"

Note that, in a pyproject.toml, each section header should be prefixed with tool.ruff. For example, [lint] should be replaced with [tool.ruff.lint].

Some configuration options can be provided via dedicated command-line arguments, such as those related to rule enablement and disablement, file discovery, and logging level:

ruff check --select F401 --select F403 --quiet

The remaining configuration options can be provided through a catch-all --config argument:

ruff check --config "lint.per-file-ignores = {'some_file.py' = ['F841']}"

To opt in to the latest lint rules, formatter style changes, interface updates, and more, enable preview mode by setting preview = true in your configuration file or passing --preview on the command line. Preview mode enables a collection of unstable features that may change prior to stabilization.

See ruff help for more on Ruff's top-level commands, or ruff help check and ruff help format for more on the linting and formatting commands, respectively.

Rules

Ruff supports over 800 lint rules, many of which are inspired by popular tools like Flake8, isort, pyupgrade, and others. Regardless of the rule's origin, Ruff re-implements every rule in Rust as a first-party feature.

By default, Ruff enables Flake8's F rules, along with a subset of the E rules, omitting any stylistic rules that overlap with the use of a formatter, like ruff format or Black.

If you're just getting started with Ruff, the default rule set is a great place to start: it catches a wide variety of common errors (like unused imports) with zero configuration.

Beyond the defaults, Ruff re-implements some of the most popular Flake8 plugins and related code quality tools, including:

For a complete enumeration of the supported rules, see Rules.

Contributing

Contributions are welcome and highly appreciated. To get started, check out the contributing guidelines.

You can also join us on Discord.

Support

Having trouble? Check out the existing issues on GitHub, or feel free to open a new one.

You can also ask for help on Discord.

Acknowledgements

Ruff's linter draws on both the APIs and implementation details of many other tools in the Python ecosystem, especially Flake8, Pyflakes, pycodestyle, pydocstyle, pyupgrade, and isort.

In some cases, Ruff includes a "direct" Rust port of the corresponding tool. We're grateful to the maintainers of these tools for their work, and for all the value they've provided to the Python community.

Ruff's formatter is built on a fork of Rome's rome_formatter, and again draws on both API and implementation details from Rome, Prettier, and Black.

Ruff's import resolver is based on the import resolution algorithm from Pyright.

Ruff is also influenced by a number of tools outside the Python ecosystem, like Clippy and ESLint.

Ruff is the beneficiary of a large number of contributors.

Ruff is released under the MIT license.

Who's Using Ruff?

Ruff is used by a number of major open-source projects and companies, including:

Show Your Support

If you're using Ruff, consider adding the Ruff badge to your project's README.md:

[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)

...or README.rst:

.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
    :target: https://github.com/astral-sh/ruff
    :alt: Ruff

...or, as HTML:

<a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff" style="max-width:100%;"></a>

License

This repository is licensed under the MIT License

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ruff-0.11.11.tar.gz (4.2 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

ruff-0.11.11-py3-none-win_arm64.whl (10.7 MB view details)

Uploaded Python 3Windows ARM64

ruff-0.11.11-py3-none-win_amd64.whl (11.6 MB view details)

Uploaded Python 3Windows x86-64

ruff-0.11.11-py3-none-win32.whl (10.5 MB view details)

Uploaded Python 3Windows x86

ruff-0.11.11-py3-none-musllinux_1_2_x86_64.whl (11.6 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

ruff-0.11.11-py3-none-musllinux_1_2_i686.whl (11.1 MB view details)

Uploaded Python 3musllinux: musl 1.2+ i686

ruff-0.11.11-py3-none-musllinux_1_2_armv7l.whl (10.1 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARMv7l

ruff-0.11.11-py3-none-musllinux_1_2_aarch64.whl (10.4 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

ruff-0.11.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (11.5 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

ruff-0.11.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl (11.2 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ s390x

ruff-0.11.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (12.1 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ppc64le

ruff-0.11.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl (12.4 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ppc64

ruff-0.11.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl (11.7 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ i686

ruff-0.11.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (10.1 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARMv7l

ruff-0.11.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (10.6 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

ruff-0.11.11-py3-none-macosx_11_0_arm64.whl (10.4 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

ruff-0.11.11-py3-none-macosx_10_12_x86_64.whl (11.1 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

ruff-0.11.11-py3-none-linux_armv6l.whl (10.2 MB view details)

Uploaded Python 3

File details

Details for the file ruff-0.11.11.tar.gz.

File metadata

  • Download URL: ruff-0.11.11.tar.gz
  • Upload date:
  • Size: 4.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.7.6

File hashes

Hashes for ruff-0.11.11.tar.gz
Algorithm Hash digest
SHA256 7774173cc7c1980e6bf67569ebb7085989a78a103922fb83ef3dfe230cd0687d
MD5 453b96ff0081ab669b47eaaaa0fd4f78
BLAKE2b-256 b253ae4857030d59286924a8bdb30d213d6ff22d8f0957e738d0289990091dd8

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-win_arm64.whl.

File metadata

  • Download URL: ruff-0.11.11-py3-none-win_arm64.whl
  • Upload date:
  • Size: 10.7 MB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.7.6

File hashes

Hashes for ruff-0.11.11-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 6c51f136c0364ab1b774767aa8b86331bd8e9d414e2d107db7a2189f35ea1f7b
MD5 0ecadca3f14e1bdedefe99a4e7dd30ab
BLAKE2b-256 ceeb09c132cff3cc30b2e7244191dcce69437352d6d6709c0adf374f3e6f476e

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-win_amd64.whl.

File metadata

  • Download URL: ruff-0.11.11-py3-none-win_amd64.whl
  • Upload date:
  • Size: 11.6 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.7.6

File hashes

Hashes for ruff-0.11.11-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 748b4bb245f11e91a04a4ff0f96e386711df0a30412b9fe0c74d5bdc0e4a531f
MD5 7e10367944eada901eb63a8f23e4469b
BLAKE2b-256 1bd9232e79459850b9f327e9f1dc9c047a2a38a6f9689e1ec30024841fc4416c

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-win32.whl.

File metadata

  • Download URL: ruff-0.11.11-py3-none-win32.whl
  • Upload date:
  • Size: 10.5 MB
  • Tags: Python 3, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.7.6

File hashes

Hashes for ruff-0.11.11-py3-none-win32.whl
Algorithm Hash digest
SHA256 1adcb9a18802268aaa891ffb67b1c94cd70578f126637118e8099b8e4adcf112
MD5 e76e68afc5b6bd8febd366978e25e54b
BLAKE2b-256 d2460e892064d0adc18bcc81deed9aaa9942a27fd2cd9b1b7791111ce468c25f

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for ruff-0.11.11-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 64ac6f885e3ecb2fdbb71de2701d4e34526651f1e8503af8fb30d4915a3fe345
MD5 b14176614c7ca57cba7a3504ddc5c9db
BLAKE2b-256 fff4f7b0b0c3d32b593a20ed8010fa2c1a01f2ce91e79dda6119fcc51d26c67b

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for ruff-0.11.11-py3-none-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 9263f9e5aa4ff1dec765e99810f1cc53f0c868c5329b69f13845f699fe74f639
MD5 a88d8a76f887158a49b48182d2d69395
BLAKE2b-256 6c6edfa4d2030c5b5c13db158219f2ec67bf333e8a7748dccf34cfa2a6ab9ebc

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for ruff-0.11.11-py3-none-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 99c28505ecbaeb6594701a74e395b187ee083ee26478c1a795d35084d53ebd81
MD5 b1c8bf52a36ff79e4c718b58b9261d72
BLAKE2b-256 b3f34be2453b258c092ff7b1761987cf0749e70ca1340cd1bfb4def08a70e8d8

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for ruff-0.11.11-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 dcec2d50756463d9df075a26a85a6affbc1b0148873da3997286caf1ce03cae1
MD5 d70890bad5e091a52765859d84a5c440
BLAKE2b-256 6fbfd7130eb26174ce9b02348b9f86d5874eafbf9f68e5152e15e8e0a392e4a3

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for ruff-0.11.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 882821fcdf7ae8db7a951df1903d9cb032bbe838852e5fc3c2b6c3ab54e39875
MD5 f69221bc6190d8279ff03c6a4a11db41
BLAKE2b-256 650d0338bb8ac0b97175c2d533e9c8cdc127166de7eb16d028a43c5ab9e75abd

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for ruff-0.11.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 6224076c344a7694c6fbbb70d4f2a7b730f6d47d2a9dc1e7f9d9bb583faf390b
MD5 54679ec37d3d78984bb20fb93abfb087
BLAKE2b-256 ff163b006a875f84b3d0bff24bef26b8b3591454903f6f754b3f0a318589dcc3

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for ruff-0.11.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 d8c4ddcbe8a19f59f57fd814b8b117d4fcea9bee7c0492e6cf5fdc22cfa563c8
MD5 150f060047a93afb1437604e3009b9c7
BLAKE2b-256 6ee3160488dbb11f18c8121cfd588e38095ba779ae208292765972f7732bfd95

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl.

File metadata

File hashes

Hashes for ruff-0.11.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl
Algorithm Hash digest
SHA256 a97c9babe1d4081037a90289986925726b802d180cca784ac8da2bbbc335f709
MD5 a486e27c171204bad1aac366da7e847f
BLAKE2b-256 61fb32e029d2c0b17df65e6eaa5ce7aea5fbeaed22dddd9fcfbbf5fe37c6e44e

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for ruff-0.11.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 e231ff3132c1119ece836487a02785f099a43992b95c2f62847d29bace3c75ac
MD5 72e67a5c1f51d21bb7c73312e64d769c
BLAKE2b-256 3d9fb4539f037a5302c450d7c695c82f80e98e48d0d667ecc250e6bdeb49b5c3

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for ruff-0.11.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 1b5ab797fcc09121ed82e9b12b6f27e34859e4227080a42d090881be888755d4
MD5 8906f58c84cb32bf56a83291912c289b
BLAKE2b-256 c4b2e2ed82d6e2739ece94f1bdbbd1d81b712d3cdaf69f0a1d1f1a116b33f9ad

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for ruff-0.11.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 7885d9a5e4c77b24e8c88aba8c80be9255fa22ab326019dac2356cff42089fc6
MD5 9e00ca6b74e8c84596927734b4205dcf
BLAKE2b-256 b450557ad9dd4fb9d0bf524ec83a090a3932d284d1a8b48b5906b13b72800e5f

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ruff-0.11.11-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d6e333dbe2e6ae84cdedefa943dfd6434753ad321764fd937eef9d6b62022bcd
MD5 91ecc1cff5c45c942d60ff03c6c3e78b
BLAKE2b-256 e2388e1a3efd0ef9d8259346f986b77de0f62c7a5ff4a76563b6b39b68f793b9

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for ruff-0.11.11-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c8a93276393d91e952f790148eb226658dd275cddfde96c6ca304873f11d2ae4
MD5 32185d5fee753a656cfb325078b13deb
BLAKE2b-256 9af3bff7c92dd66c959e711688b2e0768e486bbca46b2f35ac319bb6cce04447

See more details on using hashes here.

File details

Details for the file ruff-0.11.11-py3-none-linux_armv6l.whl.

File metadata

File hashes

Hashes for ruff-0.11.11-py3-none-linux_armv6l.whl
Algorithm Hash digest
SHA256 9924e5ae54125ed8958a4f7de320dab7380f6e9fa3195e3dc3b137c6842a0092
MD5 434b6f87495cb891760dde7040522c3a
BLAKE2b-256 b114f2326676197bab099e2a24473158c21656fbf6a207c65f596ae15acb32b9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page