tutorial · 2026-03-10

How to Show an Upload and Download Progress Bar for HTTP Transfers in UE5

Drive a UMG progress bar from real bytes-sent and bytes-received counts using EasyHTTP's On Progress callback.

EasyHTTP
Featured on Fab EasyHTTP Make HTTP requests from Blueprints without the boilerplate.
$12.99 Get on Fab →
GET, POST, PUT, PATCH, DELETE
HTTP methods supported
BytesSent / BytesReceived (int32)
Progress parameter type
8080 (HTTP)
Built-in test server port

The problem: a transfer with no feedback

If you have ever wired up an Unreal Engine HTTP upload, you have probably hit the same wall: the request fires, the screen freezes on a spinner, and the player has no idea whether their save file is halfway uploaded or stuck. For anything bigger than a tiny JSON payload, an Unreal Engine HTTP upload progress bar driven by real bytes sent is the difference between a UI that feels broken and one that feels responsive.

You do not need to drop into C++ or poll the engine's HTTP module by hand. EasyHTTP exposes a dedicated On Progress callback that reports a transfer's live byte counts as it happens, so you can map those numbers straight onto a UMG 'Progress Bar'. This tutorial covers the callback, what its two parameters mean, and the percent formula to feed the widget.

The On Progress callback

Two of EasyHTTP's call styles surface progress: the 'Easy HTTP Request With Progress' node and the latent 'Async HTTP Request' node, which exposes a separate On Progress execution pin alongside On Success and On Failure. Either way, the engine calls back repeatedly while the transfer is in flight, and each call hands you the current byte totals.

Reach for the async node when wiring this into UMG, because its On Progress pin drops naturally into an Event Graph: every time it fires you push the latest numbers into your widget. There is no manual timer or tick polling; the callback is driven by the transfer itself.

BytesSent vs BytesReceived

The callback gives you two parameters, 'BytesSent' and 'BytesReceived', both int32. The one you use depends on direction. When uploading a payload, such as a large save blob or a multipart form, watch 'BytesSent' rise toward the size of the body you handed the request. When downloading a response, watch 'BytesReceived' climb instead.

EasyHTTP buffers the full response rather than streaming it, so 'BytesReceived' reflects the body arriving into that buffer; there is no chunk-by-chunk streaming API. For an upload progress bar, bind your widget to 'BytesSent' and compare it against the total size of the content you are sending.

Wiring a UMG progress bar and calculating percent

With the callback understood, the wiring is short. The steps below assume you have a User Widget on screen containing a 'Progress Bar' named ProgressBar, and that you know the total byte size of the payload you are about to upload.

1. In your Widget Blueprint or owning actor, add the 'Async HTTP Request' node, set the Method to POST (or PUT) and supply your URL and body. Drag off the body so you can also capture its length as your total.

2. From the node's On Progress execution pin, you receive 'BytesSent' and 'BytesReceived'. For an upload, take 'BytesSent'; for a download, take 'BytesReceived'.

3. Apply the percent formula the docs give: divide the transferred bytes by the total bytes, then multiply by 100. To express this as the 0.0 to 1.0 ratio that a UMG 'Progress Bar' expects, just divide transferred by total and skip the times-100 step. Cast 'BytesSent' to float before dividing so you do not get an integer-truncated result.

4. Call 'Set Percent' on your ProgressBar with that ratio. Guard against a total of zero before dividing, so an empty or unknown-size payload does not produce a not-a-number value.

5. From On Success, snap the bar to 1.0 and hide or reset it; from On Failure, reset the bar and surface the error so the UI does not sit at a stale value.

One caveat: a real percentage requires a known total. EasyHTTP gives you the live 'BytesSent' count, but the denominator is the size of the body you supplied, so track that yourself when you build the request rather than expecting the callback to report it.

Where to go next

During development, spin up EasyHTTP's built-in local test server on port 8080 and point your upload at http://localhost:8080/ to watch the bar fill without a real backend, then inspect what arrived with 'Get Last Server Request'. For production endpoints behind a login, build your request options with an auth helper such as 'Make Options With Bearer Token', and remember that 'Retry On Connection Error' retries only on connection failures, never on a 4xx or 5xx response, so treat HTTP error codes as a finished-but-failed transfer.

EasyHTTP is Blueprint-first but fully usable from C++, and ships a BP_Examples actor and L_Demo level you can open to see the nodes wired up. If you want a visual transfer dashboard rather than a single bar, Fast Chart Widgets can plot throughput over time from the same byte counts you are already capturing.

FAQ

How do I get the bytes sent for an Unreal Engine HTTP upload progress bar?

Use EasyHTTP's 'Async HTTP Request' or 'Easy HTTP Request With Progress' node and read the On Progress callback. It fires repeatedly during the transfer and hands you 'BytesSent' (an int32). Compare that running count to the total size of the body you supplied to compute progress.

What is the difference between BytesSent and BytesReceived?

Both are int32 parameters on the On Progress callback. 'BytesSent' rises as your request body uploads, so it drives an upload progress bar. 'BytesReceived' rises as the response downloads into EasyHTTP's buffer, so it drives a download progress bar.

What formula turns bytes into a percentage?

The docs use bytes divided by total, times 100. A UMG 'Progress Bar' wants a 0.0 to 1.0 ratio instead, so divide transferred bytes by total bytes and skip the multiply. Cast to float before dividing and guard against a total of zero.

Why does my progress bar never reach 100 percent or jumps oddly?

The callback only gives you the live byte count, not the total, so the denominator is the body size you provided. If you used the wrong total, or divided two int32 values without casting to float, the ratio will truncate or stall. Track the payload size yourself and cast before dividing.

Can EasyHTTP stream a partial download for a smoother bar?

No. EasyHTTP buffers the full response rather than streaming it chunk by chunk, and it does not support WebSockets. 'BytesReceived' reflects the body filling that buffer, which is still enough to animate a download progress bar.

Get it on Fab

EasyHTTP

GET, POST, PUT and DELETE with headers, JSON parsing and async callbacks — REST APIs in a few Blueprint nodes. Talk to web services, backends and game APIs without touching C++.

$12.99USD · one-time · free updates
Report a bug