Skip to main content
pythermalcomfort logo

pythermalcomfort

pythermalcomfort is a Python toolkit for computing thermal comfort indices, heat/cold stress metrics, and thermophysiological responses. Its implementations adhere to international standards and peer-reviewed research, offering researchers, engineers, and building scientists reliable, standards-compliant calculations without the burden of implementing them manually.

Key Features

  • Thermal Comfort Models – PMV/PPD, adaptive comfort assessments, SET, and more bundled into a single API surface.

  • Heat & Cold Stress Indices – UTCI, Heat Index, Wind Chill, Humidex, and other commonly-referenced metrics.

  • Thermophysiological Modeling – two-node (Gagge) and multinode (JOS-3) models for estimating core/skin temperatures and skin wettedness.

  • Standards Compliance – Calculations based on ASHRAE 55, ISO 7730, EN 16798, and supporting references.

  • Vectorized Inputs – Accepts scalars, lists, or NumPy arrays; most functions broadcast across input arrays automatically.

  • Pythonic API – Simple, documented entry points that plug into analysis workflows and pipelines.

  • Rich Documentation – Tutorials, examples, and reference guides for each supported model and index.

  • Active Development – Frequent releases, new features, and responsive issue resolution.

  • Open Source – MIT licensed and developed transparently on GitHub.

Why Choose pythermalcomfort?

  • Precision – Accurate evaluations of comfort and stress that engineers can trust.

  • Efficiency – Eliminates repetitive code so teams can focus on insights, not implementation details.

  • Versatility – Useful in building science, HVAC design, biometeorology, sports science, and thermal physiology.

  • Evidence-Based Decisions – Supports data-driven HVAC sizing, occupant comfort strategies, and performance benchmarking.

Installation

Install from PyPI:

pip install pythermalcomfort

For alternative installation instructions, including development builds and optional dependencies, see the official docs.

Requirements

  • Python 3.10+

  • NumPy, SciPy, Numba, setuptools (installed automatically)

  • Optional: pandas, Matplotlib, or other plotting libraries for examples and visualizations

Quick Start

A few lines are all you need to get started:

from pythermalcomfort.models import pmv_ppd_iso, utci

# Calculate PMV and PPD using ISO 7730 standard
result = pmv_ppd_iso(
    tdb=25,   # dry-bulb temperature in °C
    tr=25,    # mean radiant temperature in °C
    vr=0.1,   # relative air speed in m/s
    rh=50,    # relative humidity in %
    met=1.4,  # metabolic rate in met
    clo=0.5,  # clothing insulation in clo
    model="7730-2005",
)
print(f"PMV: {result.pmv}, PPD: {result.ppd}")

# Calculate UTCI for heat stress assessment
result = utci(tdb=30, tr=30, v=0.5, rh=50)
print(result.utci)

# Most functions also accept arrays for bulk calculations
result = utci(tdb=[28, 30, 35], tr=[28, 30, 35], v=0.5, rh=50)
print(result.utci)

For a full list of models and indices, see the API reference.

Support pythermalcomfort

Maintaining an open-source scientific package takes time. You can help by:

  • Sponsoring on GitHub

  • Submitting code, docs, or tests via a pull request

  • Reporting reproducible bugs or feature requests in the issue tracker

  • Assisting with testing, translations, or PR reviews

  • Starring or sharing the project to raise awareness

Contributions

We welcome all contributions. Please read the contributing guide before you start.

Quick checklist

  • Open an issue when planning large changes to align on scope.

  • Fork the repo and create a feature branch.

  • Add or update tests for new behavior.

  • Run linters/formatters and fix the reported issues.

  • Update docs or the changelog when the public API changes.

  • Submit clear, focused PRs with related issues linked.

Common commands

# clone your fork and add upstream remote
git clone git@github.com:your-username/pythermalcomfort.git
cd pythermalcomfort
git remote add upstream git@github.com:pythermalcomfort/pythermalcomfort.git
git fetch upstream

# create a branch and work on it
git checkout -b Feature/awesome-feature
tox  # run the full matrix (slow)
tox -e py312  # run a single env
pytest -k test_name_fragment

# fix linting/formatting
ruff check --fix
ruff format
docformatter --in-place --wrap-summaries 88 --wrap-descriptions 88 pythermalcomfort/*.py

# commit and push
git add .
git commit -m "feat: short description of change"
git push origin Feature/awesome-feature

Release process

Releases are tag-driven and published via GitHub Actions Trusted Publishing (OIDC — no PYPI_API_TOKEN or TEST_PYPI_API_TOKEN secret is required).

The standard cycle is:

  1. Develop and test a release candidate on development → TestPyPI.

  2. Merge developmentmaster via pull request.

  3. Finalize the version on master → PyPI.

Step 1 — pre-release on development (TestPyPI)
git checkout development
git pull --ff-only
git fetch --tags --prune

# Start the RC cycle for the next patch release (e.g. 3.9.8 → 3.9.9rc1):
bump-my-version bump patch

# Push the bump commit and tag — this triggers tests + TestPyPI deploy:
git push
git push --tags

If the RC needs additional fixes, make the commits then create another RC:

bump-my-version bump pre_n    # e.g. 3.9.9rc1 → 3.9.9rc2
git push
git push --tags
Step 2 — open and merge a pull request from development to master

CI runs the full test suite on the PR. Once it passes, merge via GitHub.

Step 3 — finalize on master (PyPI)
git checkout master
git pull --ff-only
git fetch --tags --prune

# Strip the rc suffix to produce the stable version.
# Replace X.Y.Z with the target version (e.g. 3.9.9):
bump-my-version bump --new-version X.Y.Z patch

# Push the bump commit and tag — this triggers tests + PyPI deploy:
git push
git push --tags

Rules:

  • All RC tags (vX.Y.ZrcN) must be pushed from development.

  • All stable tags (vX.Y.Z) must be pushed from master after merging.

  • Tag format: vX.Y.Z for stable, vX.Y.ZrcN for pre-release.

  • Do not push a stable tag before the corresponding developmentmaster PR has been merged; the CI deploy job will reject it.

Getting Help

Changelog

A full list of changes per release is available in the CHANGELOG.

License

pythermalcomfort is released under the MIT License.

Stats

Changelog

4.0.3 (2026-07-20)

  • Added a Sports.CROQUET preset to sports_heat_stress_risk (clo=0.7, met=4.5, vr=0.5, duration=90).

  • Fixed the extreme-risk interpolation segment so it reaches a risk level of 4.9 exactly 5 °C above the extreme threshold, instead of reaching it early at +4.5 °C and leaving the last 0.5 °C of the range dead.

  • Fixed an inconsistency in sports_heat_stress_risk’s extreme-risk interpolation: the upper anchor temperature used internally to scale the risk level was the raw, unrounded solver output, while the t_extreme value returned to callers is rounded to one decimal. This could produce a risk level inconsistent with the documented/returned thresholds. The interpolation now uses the same rounded t_extreme that is returned.

4.0.2 (2026-06-23)

  • Improved sports heat stress risk interpolation within the extreme range: the upper anchor temperature (where risk reaches 4.9) is now computed dynamically as t_extreme + 5 °C. This makes the extreme-range scale consistent across humidity conditions — the risk always spans exactly 5 °C above the humidity-dependent extreme threshold regardless of ambient conditions.

4.0.1 (2026-06-17)

  • Added Python 3.14 support. Removed pytest-travis-fold (unmaintained, incompatible with Python 3.14) and lifted the pytest<7 cap.

  • Fixed duplicate parametrize IDs in the ridge-regression test suite, which pytest 9 now rejects (ast.Str was removed in Python 3.14).

4.0.0 (2026-06-16)

New plotting module (pythermalcomfort.plots.matplotlib)

  • ThresholdPlot — shade comfort/stress regions on any two-axis chart (e.g. operative temperature vs. relative humidity, temperature vs. air speed). Configure regions via set_regions(thresholds, labels, colors).

  • SummaryPlot — horizontal or vertical bar-summary chart built from a pandas.DataFrame; useful for comparing multiple spaces or scenarios at a glance.

  • AdaptivePlot — ready-made adaptive comfort chart for ASHRAE 55 and EN 16798, with configurable comfort bands.

  • PsychrometricPlot — psychrometric chart with overlaid comfort regions.

All classes share a common BasePlot base and centralised visual defaults (_shared.py), making it easy to apply a consistent house style.

Other changes

  • Refactored type hints across model function signatures to use a NumericInput alias (float | int | np.floating | np.integer), improving IDE auto-complete and static-analysis accuracy.

  • Added hr_to_rh utility for humidity-ratio → relative-humidity conversion.

  • Minor cooling-effect calculation streamlining and constant centralisation.

3.9.8 (2026-05-25)

  • Added optional round_output parameter to adaptive_ashrae and adaptive_en to control rounding of output values.

  • Added limit_inputs parameter to ankle_draft and vertical_tmp_grad_ppd, consistent with other model functions.

  • ankle_draft and vertical_tmp_grad_ppd now raise UserWarning when inputs exceed model applicability limits.

  • Fixed compliance attribute being included in non-ASHRAE PMV model outputs; it is now only returned by pmv_ppd_ashrae.

  • Fixed UTCI stress category mapping when units="IP"; categories were incorrectly mapped before IP unit conversion.

3.9.3 (2026-05-01)

  • Maintenance release: internal CI pipeline improvements and dependency updates. No user-facing changes.

3.9.2 (2026-04-14)

  • Updated sports_heat_stress_risk so risk_level_interpolated now uses 1.0-4.0 instead of 0.0-3.0.

  • Updated sports_heat_stress_risk to enforce the sport-specific minimum air speed (sport.vr).

3.9.1 (2026-02-25)

  • Improved speed of PHS model.

3.9.0 (2026-02-03)

  • Added sports_heat_stress_risk function to assess heat stress risk for athletes during outdoor sports activities based on environmental conditions. Addresses issue #237.

3.7.0 (2025-10-28)

  • Added machine learning model to predict skin and rectal temperature ridge_regression_predict_t_re_t_sk.

3.6.1 (2025-10-07)

  • Fix issue with disc calculation in the two_nodes_gagge model and limiting its value to 6. Close #251

  • Improve documentation for the disc function.

  • PMV ASHRAE model returns the compliance boolean value with the ASHRAE 55:2023 standard. Close #253

  • Improve formatting of models outputs to the console.

3.6.0 (2025-09-22)

3.5.1 (2025-09-15)

  • Improved documentation on how to contribute to the project

3.5.0 (2025-09-10)

  • Added the scale_winds_speed_log function to scale wind speed.

3.4.3 (2025-07-31)

  • fix: wind chill temperature was not imported in pythermalcomfort.models

3.4.2 (2025-07-22)

  • fixed unit of sweat_rate in the PHS model

3.4.1 (2025-07-14)

  • fixed some typo in the documentation

  • better formatted the code

3.4.0 (2025-06-08)

  • Added the work_capacity_dunne.

  • Added the work_capacity_hothaps.

  • Added the work_capacity_iso.

  • Added the work_capacity_niosh.

3.3.0 (2025-06-05)

  • Added the two_nodes_gagge_ji function to calculate the two-node model for older individuals

  • Added the Temperature-Humidity Index (THI).

3.2.0 (2025-05-20)

  • Added the two_nodes_gagge_sleep function to calculate the two-node model for sleeping individuals

  • Added the ESI function to calculate the Environmental Stress Index.

3.1.0 (2025-04-28)

  • Updated the PHS model in compliance with the ISO 7933:2023 standard
    • Added default‑kwarg overrides for 2023 mode (f_r, t_re, t_cr_eq)

    • removed unused variable round from default_kwargs

  • Included test cases according to the ISO 7933:2023 standard

  • Added AutoStrMixin to provide a formatted __str__ representation for result classes

3.0.1 (2025-04-14)

  • allow np.float and np.int as inputs to all functions

  • fixed documentation for phs - met units

3.0.0 (2025-02-03)

2.10.0 (2024-03-18)

  • allow n-dimensional arrays for pet_steady and speedup p_sat calculation

2.9.1 (2024-01-19)

  • Fixed error calculation of mass sweating in PET mode, the unit was incorrect

2.9.0 (2024-01-15)

  • The PHS model accepts arrays as inputs

2.8.11 (2023-10-26)

  • wrote more test and improved code

2.8.11 (2023-10-26)

  • fixed issues with the documentation and sorted the models in alphabetical order

2.8.7 (2023-10-23)

  • Adaptive ASHRAE now returns a dataclass

2.8.6 (2023-10-09)

  • re-structured and linted the code

2.8.4 (2023-09-20)

  • calculation of cooling effect in pmv (standard=’ashrae’) triggered only when v>0.1 m/s

2.8.3 (2023-09-14)

  • general improvements in the JOS3 model

2.8.2 (2023-09-04)

  • general improvements in the JOS3 model

  • fixed error when e_max == 0

2.8.1 (2023-07-05)

  • pythermalcomfort needs Python version > 3.8

  • fixed issue in Cooling Effect calculation

2.8.0 (2023-07-03)

  • allowing the cooling effect to range from 0 to 40

  • fixed PHS documentation

  • improved JOS3 documentation

2.7.0 (2023-02-16)

  • changed coefficient of vasodilation in set_tmp() to 120 to match ASHRAE 55 2020 code

  • slightly modified value in validation tables

2.6.0 (2023-01-17)

  • max sweating rate can be passed to two node model

  • max skin wettedness can be passed to two node model

  • rounding w to two decimals

  • use_fans_heatwave function accepts arrays

  • fixed typos unit documentation

2.5.4 (2022-10-12)

  • PHS model accepts all required inputs to be run on a minute by minute basis

  • fix error check compliance PHS model

2.5.0 (2022-06-13)

  • Added the adaptive thermal heat balance (ATHB) model

2.4.0 (2022-06-10)

  • Added e_pmv model - Adjusted Predicted Mean Votes with Expectancy Factor

  • Added a_pmv model - Adaptive Predicted Mean Vote

2.3.0 (2022-06-01)

  • Added discomfort index

2.2.0 (2022-05-17)

  • Implemented a better equation to calculate the mean radiant temperature

2.1.1 (2022-05-17)

  • Fixed how DISC is calculated

2.1.0 (2022-04-20)

  • Added Physiological Equivalent Temperature (PET) model

  • In PMV and PPD function you can specify if occupants has control over airspeed

2.0.2 (2022-04-12)

  • UTCI accepts lists as inputs

2.0.0 (2022-04-07)

  • Allowing users to pass Numpy arrays or lists as input to the pmv_ppd, pmv, clo_tout, both adaptive models, utci, set_tmp, two_nodes

  • Changed the input variable from return_invalid to limit_input

  • Increased speed by using Numba @vectorize decorator

  • Changed ASHRAE 55 2020 limits to match new addenda

  • Improved documentation

1.11.0 (2022-03-16)

  • Allowing users to pass a Numpy array as input into the UTCI function

  • Numpy is now a requirement of pythermalcomfort

  • Improved PMV, JOS-3, and UTCI documentation

  • Testing PMV, SET, and solar gains models using online reference tables

1.10.0 (2021-11-15)

  • Added JOS-3 model

1.9.0 (2021-10-07)

  • Added Normal Effective Temperature (NET)

  • Added Apparent Temperature (AT)

  • Added Wind Chill Index (WCI)

1.8.0 (2021-09-28)

  • Gagge’s two-node model

  • Added WBGT equation

  • Added Heat index (HI)

  • Added humidex index

1.7.1 (2021-09-08)

  • Added ASHRAE equation to calculate the operative temperature

1.7.0 (2021-07-29)

  • Implemented function to calculate the if fans are beneficial during heatwaves

  • Fixed error in the SET equation to calculated radiative heat transfer coefficient

  • Fixed error in SET definition

  • Moved functions optimized with Numba to new file

1.6.2 (2021-07-08)

  • Updated equation clo_dynamic based on ANSI/ASHRAE Addendum f to ANSI/ASHRAE Standard 55-2020

  • Fixed import errors in examples

1.6.1 (2021-07-05)

  • optimized UTCI function with Numba

1.6.0 (2021-05-21)

  • (BREAKING CHANGE) moved some of the functions from psychrometrics to utilities

  • added equation to calculate body surface area

1.5.2 (2021-05-05)

  • return stress category UTCI

1.5.1 (2021-04-29)

  • optimized phs with Numba

1.5.0 (2021-04-21)

  • added Predicted Heat Strain (PHS) index from ISO 7933:2004

1.4.6 (2021-03-30)

  • changed equation to calculate convective heat transfer coefficient in set_tmp() as per Gagge’s 1986

  • fixed vasodilation coefficient in set_tmp()

  • docs changed term air velocity with air speed and improved documentation

  • added new tests for comfort functions

1.3.6 (2021-02-04)

  • fixed error calculation solar_altitude and sharp for supine person in solar_gain

1.3.5 (2021-02-02)

  • not rounding SET temperature when calculating cooling effect

1.3.3 (2020-12-14)

  • added function to calculate sky-vault view fraction

1.3.2 (2020-12-14)

  • replaced input solar_azimuth with sharp in the solar_gain() function

  • fixed small error in example pmv calculation

1.3.1 (2020-10-30)

  • Fixed error calculation of cooling effect with elevated air temperatures

1.3.0 (2020-10-19)

  • Changed PMV elevated air speed limit from 0.2 to 0.1 m/s

1.2.3 (2020-09-09)

  • Fixed error in the calculation of erf

  • Updated validation table erf

1.2.2 (2020-08-21)

  • Changed default diameter in mean_radiant_tmp

  • Improved documentation

1.2.0 (2020-07-29)

  • Significantly improved calculation speed using numba. Wrapped set and pmv functions

1.0.6 (2020-07-24)

  • Minor speed improvement changed math.pow with **

  • Added validation PMV validation table from ISO 7730

1.0.4 (2020-07-20)

  • Improved speed calculation of the Cooling Effect

  • Bisection has been replaced with Brentq function from scipy

1.0.3 (2020-07-01)

  • Annotated variables in the SET code.

1.0.2 (2020-06-11)

  • Fixed an error in the bisection equation used to calculated Cooling Effect.

1.0.0 (2020-06-09)

  • Major stable release.

0.7.0 (2020-06-09)

  • Added equation to calculate the dynamic clothing insulation

0.6.3 (2020-04-11)

  • Fixed error in calculation adaptive ASHRAE

  • Added some examples

0.6.3 (2020-03-17)

  • Renamed function to_calc to t_o

  • Fixed error calculation of relative air speed

  • renamed input parameter ta to tdb

  • Added function to calculate mean radiant temperature from black globe temperature

  • Added function to calculate solar gain on people

  • Added functions to calculate vapour pressure, wet-bulb temperature, dew point temperature, and psychrometric data from dry bulb temperature and RH

  • Added authors

  • Added dictionaries with reference clo and met values

  • Added function to calculate enthalpy_air

0.5.2 (2020-03-11)

  • Added function to calculate the running mean outdoor temperature

0.5.1 (2020-03-06)

  • There was an error in version 0.4.2 in the calculation of PMV and PPD with elevated air speed, i.e. vr > 0.2 which has been fixed in this version

  • Added function to calculate the cooling effect in accordance with ASHRAE

0.4.1 (2020-02-17)

  • Removed compatibility with python 2.7 and 3.5

0.4.0 (2020-02-17)

  • Created adaptive_EN, v_relative, t_clo, vertical_tmp_gradient, ankle_draft functions and wrote tests.

  • Added possibility to decide with measuring system to use SI or IP.

0.3.0 (2020-02-13)

  • Created set_tmp, adaptive_ashrae, UTCI functions and wrote tests.

  • Added warning to let the user know if inputs entered do not comply with Standards applicability limits.

0.1.0 (2020-02-11)

  • Created pmv, pmv_ppd functions and wrote tests.

  • Documented code.

0.0.0 (2020-02-11)

  • First release on PyPI.

Download files

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

Source Distribution

pythermalcomfort-4.0.3.tar.gz (2.5 MB view details)

Uploaded Source

Built Distribution

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

pythermalcomfort-4.0.3-py2.py3-none-any.whl (277.5 kB view details)

Uploaded Python 2Python 3

File details

Details for the file pythermalcomfort-4.0.3.tar.gz.

File metadata

  • Download URL: pythermalcomfort-4.0.3.tar.gz
  • Upload date:
  • Size: 2.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for pythermalcomfort-4.0.3.tar.gz
Algorithm Hash digest
SHA256 a75e4c52aa33d4704fc6ad3415e6795405c07f4fd21530ce2cc159ca8a88adcf
MD5 e1bdaba7c2bb11bab08588bf7842c1fe
BLAKE2b-256 20ca2042715d1d15d8399c7cf25d7187e34a3a8ed7d708040937047694ece516

See more details on using hashes here.

Provenance

The following attestation bundles were made for pythermalcomfort-4.0.3.tar.gz:

Publisher: build-test-publish.yml on pythermalcomfort/pythermalcomfort

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pythermalcomfort-4.0.3-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for pythermalcomfort-4.0.3-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 f87ea530334613cc58cc6c648bd369bfc4719ec8fa5f5bc243f5e323ffa76839
MD5 52e8e86b6931f8363c3e1842f97a852e
BLAKE2b-256 e867b6471b82811a1ae8814f31f7c4b54c3e9016d900ed43ab8a68edcee7e3d3

See more details on using hashes here.

Provenance

The following attestation bundles were made for pythermalcomfort-4.0.3-py2.py3-none-any.whl:

Publisher: build-test-publish.yml on pythermalcomfort/pythermalcomfort

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

4.4.2

2 files

4.4.1

2 files

4.4.0

2 files

4.3.0

2 files

4.2.0

2 files

4.1.1

2 files

4.1.0

2 files

This release

4.0.3 This release

2 files

4.0.2

2 files

4.0.1

2 files

4.0.0

2 files

3.9.8

2 files

3.9.3

2 files

3.9.2

2 files

3.9.1

2 files

3.9.0

2 files

3.8.0

2 files

3.7.1

2 files

3.7.0

2 files

3.6.1

2 files

3.5.1

2 files

3.5.0

2 files

3.4.4

2 files

3.4.3

2 files

3.4.2

2 files

3.4.1

2 files

3.3.0

2 files

3.2.0

2 files

3.1.2

2 files

3.1.1

2 files

3.1.0

2 files

3.0.1

2 files

3.0.0

2 files

2.10.0

2 files

2.9.2

2 files

2.9.1

2 files

2.9.0

2 files

2.8.12

2 files

2.8.10

2 files

2.8.9

2 files

2.8.8

2 files

2.8.7

2 files

2.8.4

2 files

2.8.3

2 files

2.8.2

2 files

2.8.1

2 files

2.8.0

2 files

2.7.2

2 files

2.7.1

2 files

2.7.0

2 files

2.6.0

2 files

2.5.4

2 files

2.5.3

2 files

2.5.2

2 files

2.5.1

2 files

2.5.0

2 files

2.4.0

2 files

2.3.0

2 files

2.2.0

2 files

2.1.1

2 files

2.1.0

2 files

2.0.2

2 files

2.0.1

2 files

2.0.0

2 files

1.11.0

2 files

1.10.0

2 files

1.9.0

2 files

1.8.0

2 files

1.7.1

2 files

1.7.0

2 files

1.6.2

2 files

1.6.1

2 files

1.6.0

2 files

1.5.2

2 files

1.5.1

2 files

1.5.0

2 files

1.4.5

2 files

1.4.2

2 files

1.4.1

2 files

1.4.0

2 files

1.3.6

2 files

1.3.5

2 files

1.3.4

2 files

1.3.3

2 files

1.3.2

2 files

1.3.1

2 files

1.3.0

2 files

1.2.3

2 files

1.2.2

2 files

1.2.1

2 files

1.2.0

2 files

1.1.0

2 files

1.0.6

2 files

1.0.5

2 files

1.0.4

2 files

1.0.3

2 files

1.0.2

2 files

1.0.1

2 files

1.0.0

2 files

0.7.0

2 files

0.6.4

2 files

0.6.3

2 files

0.6.2

2 files

0.6.1

2 files

0.6.0

2 files

0.5.2

2 files

0.5.1

2 files

0.5.0

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

0.3.0

2 files

0.1.0

2 files

0.0.0

2 files

Supported by

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