# Peek Messages (/sdks/csharp/how-to/queues/peek-messages)



## Overview [#overview]

Peeking lets you look at what's sitting in a queue without touching it — the messages stay exactly where they are, still waiting for whichever consumer eventually receives them. It's the tool you reach for when you need visibility into queue state — checking backlog depth, inspecting payloads while debugging a stuck pipeline, or building an operational dashboard — without risking a collision with real consumers competing for the same work.

`PeekQueueMessagesAsync` is a variant of the same request your consumers use, just in read-only mode: it takes the same `Channel`, `MaxMessages`, and `WaitTimeoutSeconds`, but the broker returns a copy of the messages without marking them as delivered, locking them, or starting a visibility timeout — so no acknowledgment is needed or even possible.

**Gotchas:** peeked messages aren't reserved for you — a consumer polling the same channel concurrently can receive and remove them the instant after you peek, so treat the count as a point-in-time estimate, not a guarantee. Peek also won't surface messages already locked inside another consumer's in-flight poll, and it's not a substitute for receiving when you actually intend to process what you see.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000`
* C# SDK installed (`dotnet add package KubeMQ.SDK.CSharp`)

## Code [#code]

```csharp title="Program.cs"
// KubeMQ .NET SDK — Queues: Peek Messages
//
// This example demonstrates peeking at queue messages without consuming them.
// Peeked messages remain in the queue and can still be received by consumers.
//
// Prerequisites:
//   - KubeMQ server running on localhost:50000
//   - Send some messages to "csharp-queues.peek" first
//   - dotnet run

using KubeMQ.Sdk.Client;
using KubeMQ.Sdk.Queues;
using System.Text;

await using var client = new KubeMQClient(new KubeMQClientOptions
{
    ClientId = "csharp-queues-peek-client",
});
await client.ConnectAsync();

Console.WriteLine("Connected to KubeMQ server");

var response = await client.PeekQueueMessagesAsync(new QueuePollRequest
{
    Channel = "csharp-queues.peek",
    MaxMessages = 5,
    WaitTimeoutSeconds = 3,
});

Console.WriteLine($"Peeked {response.Messages.Count} messages (not consumed)");

foreach (var msg in response.Messages)
{
    Console.WriteLine($"  {msg.MessageId}: {Encoding.UTF8.GetString(msg.Body.Span)}");
}

Console.WriteLine("Done.");

```

## How It Works [#how-it-works]

* `PeekQueueMessagesAsync` reads messages non-destructively: the broker returns a copy of the messages but does not change their state. They remain in the queue and will be delivered to the next consumer that polls.
* This is useful for debugging, monitoring queue depth, or building dashboards without affecting consumers.
* `MaxMessages` caps the number of messages returned in one peek; `WaitTimeoutSeconds` sets how long the server waits if the queue is currently empty.
* Peek does not lock messages — if a consumer polls the same channel concurrently, it can receive the same messages that were peeked.

## Related [#related]

* [Pattern overview](/learn/queues/getting-started)
* [C# SDK Reference](/sdks/csharp/reference)
* [Send & Receive](/sdks/csharp/tutorials/send-receive)
* [Ack All](/sdks/csharp/how-to/queues/ack-all)
