Skip to content

Technology · Concurrency in Rust

Concurrent services in Rust with Tokio

Tokio is the foundation on which almost everything in Rust that does several things at once is written: handling connections, talking to devices, moving files, waiting for answers. It lets a single program keep thousands of tasks in progress with very few resources. We use it for services that cannot stop and for the background work of desktop apps.

Often combined with

Fig. 01Roundhouse of tasksSTOP34251ONE BRIDGE · MANY TRACKSLooping
A single turntable bridge serves every track: it stops at the one whose light is on and does not wait for the one that never answers. That one runs out of time on the clock, and the lever stops the service in good order.

Situations

What you can solve with Tokio

Tokio pays off when a program spends most of its time waiting, on the network, the disk or a machine, and cannot afford one wait holding up the others.

  • Many devices and a single program

    Dozens or hundreds of sensors, readers or machines that send data whenever they like. Each one is a lightweight task; the slow one does not delay the others.

  • A service that hangs

    A slow request blocks the rest, or a connection that does not answer leaves the program waiting forever. Here every wait has its maximum time and its way of being canceled.

  • Background work inside an app

    Synchronizing, importing a large file or watching a folder while the person keeps working, without the window freezing.

  • Data that has to arrive right away

    Telemetry, alerts or changes that are sent as they happen, over an open connection, to many clients at once.

Two tracks: the ready one gets the bridge; the other waits without holding it

What to check before starting

  • How many connections or devices there are at once and how long each takes to answer
  • What should happen when one does not reply
  • Which work is waiting and which is intensive calculation
  • How the service is stopped without losing what was half done

Services

What we build with Tokio

Four kinds of job. All four are the same craft: a program doing many things at once without any of them bringing down the others.

  • Module 1 · Tracks

    Services with many connections

    Programs that keep many connections open at once, with devices, with clients or with other systems, and share out the work without one blocking another.

    Examples of deliverables

    • Concentrator for sensor readings
    • Gateway between machines and server
    • Internal messaging service
  • Module 2 · Turntable

    Background work and queues

    Tasks that run while the application keeps responding: imports, synchronization, folder watching, with their queue, their limit on simultaneous jobs and their progress.

    Examples of deliverables

    • Import of large files
    • Synchronization with the server
    • Job queue with a limit
  • Module 3 · Channel

    Real time and data streams

    Data that passes from one task to another through channels and goes out as it arrives, with control so the producer does not overwhelm the consumer.

    Examples of deliverables

    • Dashboard with live data
    • Event relay over WebSocket
    • Processing of a continuous stream
  • Module 4 · Clock

    Timeouts, retries and shutdown

    What separates a service that holds up from one that has to be restarted: every wait has a limit, every failure its measured retry, and shutdown finishes what is half done.

    Examples of deliverables

    • Maximum time per operation
    • Retries with growing waits
    • Shutdown without losing work

A working example

Sixteen devices and one that does not answer

Simulated demonstration. Sixteen devices send one reading each; number 7 does not respond. Run the round serving them one by one and then all at once, with and without a maximum wait.

Simulated demo · sample data

How they are served

Outcome of the round

Choose how to serve them and run the round.

Devices

  1. Device 1waiting
  2. Device 2waiting
  3. Device 3waiting
  4. Device 4waiting
  5. Device 5waiting
  6. Device 6waiting
  7. Device 7waiting
  8. Device 8waiting
  9. Device 9waiting
  10. Device 10waiting
  11. Device 11waiting
  12. Device 12waiting
  13. Device 13waiting
  14. Device 14waiting
  15. Device 15waiting
  16. Device 16waiting

The devices and their delays are simulated in your browser. What changes between one mode and another is what changes in a real service: who waits for whom, and what happens when someone does not answer.

Integration

How it fits with your systems

Tokio is not seen: it is what sits underneath a service or an app when they do several things at once. Around it are those who talk to it and those it answers.

Where it comes from

  • Devices and sensorsreadings as they happen
  • Clients and other appsopen connections
  • Files and queuespending work
TokioRust service with Tokiomany tasks, few resources

Where it goes

Dependencies worth checking

  • Which libraries for the devices or services are asynchronous and which block
  • Where there is heavy calculation that should go to separate threads
  • Which metrics and traces are needed to see what is going on
  • How it is deployed and who watches it

How we work and what we deliver

How we work on a Tokio job

  1. 01

    Initial review

    We look at what the service has to handle at once, how long each thing takes and what fails today under load.

  2. 02

    Scope

    We write down the tasks, their limits, what happens when something does not respond and how it shuts down; and what is left out.

  3. 03

    First release

    The service running with your devices, or with a faithful simulation of them, and its metrics in view.

  4. 04

    Validation

    You test it with real load, unplugging devices and cutting the network halfway.

  5. 05

    Documentation

    The map of tasks, the limits chosen and why, and how to read the metrics.

What you get when the job closes

  • The code of the service in your repository, with its tests
  • The executable or the image to deploy it
  • A dashboard or a log where you can see what it is doing
  • The list of what is left out, and why

Questions

Questions about Tokio

Missing yours? Write it to info@veodar.com and we'll reply with a specific question, not a brochure.

What exactly is Tokio?

It is a Rust library, the most widely used for asynchronous programming. It takes care of sharing many tasks among a few processor threads, so that a task that is waiting occupies nobody. Most of the servers, database clients and network libraries in the ecosystem are built on it.

Does my desktop application need it?

If it does anything more than show forms, almost certainly: synchronizing, talking to a device or importing a file without freezing the window is asynchronous work. In an app built with Tauri, Tokio is already underneath.

How is it different from doing it with Node.js?

The idea is similar: not blocking while you wait. The difference is that Rust uses every processor core, spends less memory and checks at compile time that two tasks do not step on the same data. For a service that moves a lot of data or must always be up, that matters; for a simple integration, Node.js is usually enough.

What happens if a device stops responding?

Whatever was decided, and it is decided beforehand: wait a maximum time, retry a few times with growing pauses, mark it as down and raise an alert. What cannot happen is the whole service sitting there waiting.

Is it suitable for heavy calculation?

That is not its role. Tokio shines when there are many waits; intensive calculation is sent to separate threads so it does not slow the rest. Part of the design consists of separating the two things well.

How do you know what a service like this is doing?

With metrics and traces from day one: how many tasks are in progress, how long they wait, which ones fail. Without that, a concurrent service is a black box, so it is part of the delivery.

Updated:

Other technologies

What it is combined with

All technologies
  • Rust developmentApplications, services and modules that cannot fail or run slow. We write the core of your product in Rust, or the piece that is holding it back today.
  • APIs and backends in Rust with AxumWeb services in Rust that respond fast and use little. Every request is checked for its shape before it reaches your logic.
  • Desktop apps with TauriApplications for Windows, macOS and Linux with a web interface and a Rust core: light installers and scoped permissions. New, or migrated from Electron.

Get started

Tell us what your service has to handle at once.

Knowing how many devices or connections there are and what fails today is enough for a first answer.

What helps us assess it

  • Which devices, clients or systems connect
  • How many at once and how often
  • What happens today when one fails
  • Where it runs: a machine, a server, the cloud

Before you write, see how we price a project or our solutions by department.

Fig. 07Morse keyH · E · L · L · O