.NETMedium
What is the difference between Task and ValueTask in C#?
Task is a reference type and always allocates on the heap, even when the async method completes synchronously. ValueTask is a struct that avoids allocation when the result is already available — useful for hot paths like cache lookups.
public ValueTask<User?> GetUserAsync(Guid id) {
if (_cache.TryGetValue(id, out var u)) return new ValueTask<User?>(u); // zero alloc
return new ValueTask<User?>(LoadFromDbAsync(id)); // wraps a Task
}
Rules of thumb:
- Use
ValueTaskonly when synchronous completion is the common case (>50% of calls) - Never await a
ValueTasktwice — it can be backed by a pooled object - Stick with
Taskfor I/O-heavy methods; the allocation cost is negligible compared to the I/O
In .NET 9 the JIT inlines many ValueTask paths so the gap has narrowed; use the simpler Task unless profiling shows allocation pressure.