# Peek Messages (/sdks/kotlin/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.

`peekQueueMessages { }` is a variant of the same request `receiveQueuesMessages { }` uses, just in read-only mode: the broker returns a snapshot of messages currently queued, marked by the `isPeek` flag on the response, but never locks or removes them — so no acknowledgment is needed or even possible.

**Gotchas:** peeked messages aren't reserved for you — a consumer can `receiveQueuesMessages` 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 receive, 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`
* Kotlin SDK installed (`implementation("io.kubemq.sdk:kubemq-sdk-kotlin:1.0.1")`)

## Code [#code]

```kotlin title="PeekMessagesExample.kt"
package io.kubemq.sdk.examples.queues

import io.kubemq.sdk.client.KubeMQClient
import io.kubemq.sdk.queues.queueMessage
import kotlinx.coroutines.runBlocking

private const val ADDRESS = "localhost:50000"
private const val CLIENT_ID = "kotlin-queues-peek-messages"
private const val CHANNEL = "kotlin-queues.peek-messages"

fun main() = runBlocking {
    val client = KubeMQClient.queues {
        address = ADDRESS
        clientId = CLIENT_ID
    }

    client.use {
        // Send messages
        repeat(3) { i ->
            client.sendQueuesMessage(queueMessage {
                channel = CHANNEL
                body = "Peek msg #${i + 1}".toByteArray()
            })
        }
        println("Sent 3 messages.")

        // Peek -- non-destructive read (messages remain in queue)
        val peekResp = client.peekQueueMessages {
            channel = CHANNEL
            maxNumberOfMessages = 5
            waitTimeSeconds = 3
        }
        println("\nPeeked ${peekResp.messages.size} messages (isPeek=${peekResp.isPeek}):")
        peekResp.messages.forEach { println("  ${String(it.body)}") }

        // Verify messages are still in queue by receiving them
        val recvResp = client.receiveQueuesMessages {
            channel = CHANNEL
            maxItems = 10
            waitTimeoutMs = 3000
            autoAck = true
        }
        println("\nAfter peek, received ${recvResp.messages.size} messages (still in queue).")

        println("Done.")
    }
}
```

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

* `peekQueueMessages { }` performs a non-destructive read -- messages remain in the queue.
* The `isPeek` flag on the response confirms it was a peek operation.
* After peeking, messages can still be received normally with `receiveQueuesMessages`.
* Useful for monitoring queue depth or inspecting messages without consuming them.

## Related [#related]

* [Send & Receive](/sdks/kotlin/tutorials/send-receive)
* [Poll Mode](/sdks/kotlin/how-to/queues/poll-mode)
* [Queues Reference](/sdks/kotlin/reference/queues)
