Skip to main content

Tremolo

Coverage Quality Gate Status

Tremolo is a stream-oriented, asynchronous, programmable HTTP server written in pure Python. It can also serve as an ASGI server for other ASGI web frameworks.

Being built with a stream in mind, Tremolo tends to use yield instead of return in route handlers.

@app.route('/hello')
async def hello_world(**server):
    yield b'Hello '
    yield b'World!'

But that's not the only pattern. You can go straight to the Basics to start building your web application with Tremolo.

Features

Tremolo is only suitable for those who value minimalism and stability over features.

With only 3k lines of code, with no dependencies other than the Python Standard Library, it gives you:

All built-in in a single, portable folder module tremolo, in a very compact way like a Swiss Army knife.

Installation

python3 -m pip install --upgrade tremolo

Example

Here is a complete hello world example in case you missed the usual return.

from tremolo import Application

app = Application()

@app.route('/hello')
async def hello_world(**server):
    return 'Hello World!', 'latin-1'


if __name__ == '__main__':
    app.run('0.0.0.0', 8000, debug=True)

Well, latin-1 on the right side is not required. The default is utf-8.

You can save it as hello.py and just run it with python3 hello.py. And your first hello world page with Tremolo will be at http://localhost:8000/hello.

ASGI Server

Tremolo is an HTTP Server framework. You can build abstractions on top of it, say an ASGI server.

In fact, Tremolo already has ASGI server (plus WebSocket) implementation. So you can immediately use existing ASGI applications / frameworks, on top of Tremolo (ASGI server).

For example, If a minimal ASGI application with the name example.py:

async def app(scope, receive, send):
    assert scope['type'] == 'http'

    await send({
        'type': 'http.response.start',
        'status': 200,
        'headers': [
            (b'content-type', b'text/plain')
        ]
    })
    await send({
        'type': 'http.response.body',
        'body': b'Hello, World!'
    })

Then you can run as follows:

python3 -m tremolo --debug --bind 127.0.0.1:8000 example:app

To see more available options:

python3 -m tremolo --help

It's also possible to run the ASGI server programmatically (example with uvloop):

python3 example_uvloop.py

Testing

Just run python3 alltests.py for all tests. Or individual test_*.py in the tests/ folder, for example python3 tests/test_cli.py.

If you also want measurements with coverage:

coverage run alltests.py
coverage combine
coverage report
coverage html # to generate html reports

Benchmarking

The first thing to note is that Tremolo is a pure Python server framework.

As a pure Python server framework, it is hard to find a comparison. Because most servers/frameworks today are full of steroids like httptools, uvloop, Rust, etc.

You can try comparing with Uvicorn with the following option (disabling steroids to be fair):

uvicorn --loop asyncio --http h11 --log-level error example:app

vs

python3 -m tremolo --log-level ERROR example:app

You will find that Tremolo is reasonably fast.

If it's not, it could be due to --upload-rate or --download-rate limits, which take effect when the payload is slightly larger. Despite causing benchmarks to show poor results, it prevents any single client from monopolizing bandwidth, ensuring responsiveness under heavy load.

However, it should be noted that bottlenecks often occur on the application side. Which means that in real-world usage, throughput reflects more on the application than the server.

Misc.

Tremolo utilizes SO_REUSEPORT (Linux 3.9+) to load balance worker processes.

app.run('0.0.0.0', 8000, worker_num=2)

Tremolo can also listen to multiple ports in case you are using an external load balancer like Nginx / HAProxy.

app.listen(8001)
app.listen(8002)

app.run('0.0.0.0', 8000)

You can even get higher concurrency with PyPy or uvloop:

python3 -m tremolo --loop uvloop --log-level ERROR example:app

See: --loop

License

MIT License

Release files for tremolo 0.5.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tremolo 0.5.2
File Size Uploaded
tremolo-0.5.2.tar.gz 41.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tremolo 0.5.2
File Interpreter ABI Platform
tremolo-0.5.2-py3-none-any.whl Python 3 none any Details

Total release size: 90.5 kB

Release files / tremolo-0.5.2.tar.gz

Download URL tremolo-0.5.2.tar.gz
Size 41.5 kB
Tags Source
SHA-256 checksum
How to use checksums
050e3673000e6902161d8d1a06f845ec85b3bbe20c719374038267bd2af6e80c
BLAKE2b-256 checksum
How to use checksums
4a520cf913e485eb1832d02a076de8c2a792a04e6808824e60ec56886410b073
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 1, 2026.

Transparency log

Release files / tremolo-0.5.2-py3-none-any.whl

Download URL tremolo-0.5.2-py3-none-any.whl
Size 49.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b44d6d014b6c702fa6c015d6c8bc77bcc2498f116c9a9cf09636d7b7eae559ef
BLAKE2b-256 checksum
How to use checksums
9daa6eb0211725dceced7367671c815c60cf1ce018aa5ddef9ee8f19841a2c5c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 1, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.5.2 This release

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.20

2 release files

0.4.19

2 release files

0.4.17

2 release files

0.4.16

2 release files

0.4.15

2 release files

0.4.14

2 release files

0.4.13

2 release files

0.4.9

2 release files

0.4.7

2 release files

0.4.6

2 release files

0.4.5

2 release files

0.4.4

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.11

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.321

1 release file

0.0.316

1 release file

0.0.312

1 release file

0.0.205

1 release file

0.0.115

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page