# DrawMarker in FiveM: every marker type, every parameter, and how to keep it cheap

> The FiveM DrawMarker reference: all marker types 0–43, what each of the 24 parameters does, custom texture markers and a distance loop that does not cost FPS.

Source: https://fam-tools.com/guides/fivem-drawmarker-types · FAM Tools · published 2026-09-19 · updated 2026-09-19 · about 8 min

**Short answer.** `DrawMarker(type, x, y, z, dirX, dirY, dirZ, rotX, rotY, rotZ, scaleX, scaleY, scaleZ, r, g, b, a, bob, faceCamera, rotationOrder, rotate, textureDict, textureName, drawOnEnts)` draws one marker for one frame. Types run from 0 to 43: 1 is the ground cylinder, 2 the chevron, 20–22 stacked chevrons, 25 a thin ground ring and 27 the split-arrow circle. Call it only for markers within about 20–30 metres, sleeping the loop for a second when nothing is near.

## Key points

- `DrawMarker` lasts one frame; it must be called every frame while visible.
- Only draw markers near the player; sleep the loop when none are close.
- Type 1 (cylinder) and 25/27 (ground rings) are the common ground markers; 2 and 20–22 are floating chevrons.
- Use `nil` for the texture arguments unless you are drawing a custom-texture marker.
- Types 8 and 9 are flat planes that accept a custom texture from a streamed .ytd.
- For interaction, pair the marker with a distance check and a key press, or use a target system instead.

Markers are the circles on the ground outside garages, the chevrons above job pickups and the floating arrows at shop doors. They are drawn with a single native, `DrawMarker`, that takes 24 arguments and has to be called every single frame. That combination produces two classic problems on FiveM servers: code full of unexplained `0.0, 0.0, 0.0, 0.0, 180.0` sequences nobody dares touch, and resources that draw fifty markers every frame across the whole map and cost players frame time for no reason. This page is the reference for the types and parameters, plus the loop pattern that keeps markers essentially free.

## The parameters

The native's arguments fall into groups. Once you see the groups, any `DrawMarker` call becomes readable.

| Parameter(s) | Meaning | Typical value |
| --- | --- | --- |
| `type` | Marker shape, 0–43 | 1, 2, 20, 25, 27 |
| `posX, posY, posZ` | World position of the marker centre | Ground z minus ~0.98 for ground markers |
| `dirX, dirY, dirZ` | Direction vector, used by some shapes | 0.0, 0.0, 0.0 |
| `rotX, rotY, rotZ` | Rotation in degrees | 0.0, 0.0, 0.0; 180.0 on X flips a chevron |
| `scaleX, scaleY, scaleZ` | Size on each axis | 1.0–2.0 wide, 0.5–1.0 tall |
| `red, green, blue, alpha` | Colour, 0–255 | Alpha 100–180 |
| `bobUpAndDown` | Floats up and down | true for pickups |
| `faceCamera` | Turns to face the camera | true for flat icons |
| `rotationOrder` | Euler rotation order | 2 |
| `rotate` | Spins slowly around Z | true for chevrons |
| `textureDict, textureName` | Custom texture, for texture-capable types | `nil, nil` |
| `drawOnEnts` | Projects onto entities it intersects | false |

*client.lua — one marker, fully annotated*

```lua
DrawMarker(
    1,                          -- type: vertical cylinder
    215.8, -810.1, 29.7,        -- position (ground z - 1.0)
    0.0, 0.0, 0.0,              -- direction
    0.0, 0.0, 0.0,              -- rotation
    1.5, 1.5, 0.6,              -- scale
    40, 130, 255, 140,          -- colour + alpha
    false,                      -- bob up and down
    false,                      -- face camera
    2,                          -- rotation order
    false,                      -- rotate
    nil, nil,                   -- texture dictionary / name
    false                       -- draw on entities
)
```

## Marker types 0–43

The names below are the ones used in the Cfx documentation's marker reference. Types 41 and 43 are unnamed there; test them in game before relying on them.

| Id | Name | Id | Name |
| --- | --- | --- | --- |
| 0 | Upside-down cone | 22 | Chevron up ×3 |
| 1 | Vertical cylinder | 23 | Horizontal circle, fat |
| 2 | Thick chevron up | 24 | Replay icon |
| 3 | Thin chevron up | 25 | Horizontal circle, skinny |
| 4 | Checkered flag, rectangle | 26 | Skinny circle with arrow |
| 5 | Checkered flag, circle | 27 | Split-arrow circle |
| 6 | Vertical circle | 28 | Debug sphere |
| 7 | Plane model | 29 | Dollar sign |
| 8 | Lost MC logo, transparent | 30 | Horizontal bars |
| 9 | Lost MC logo | 31 | Wolf head |
| 10–19 | Numbers 0–9 | 32 | Question mark |
| 20 | Chevron up ×1 | 33–39 | Plane, helicopter, boat, car, motorcycle, bike, truck symbols |
| 21 | Chevron up ×2 | 40 | Parachute symbol |
|  |  | 42 | Sawblade symbol |

In practice most servers use six of these: 1 for classic ground cylinders, 25 or 27 for flat rings on the ground, 2 or 20 for a floating chevron above an interaction point, 29 for money-related spots, and 36 for vehicle spawn and garage points. Type 28, the debug sphere, is ideal during development for visualising a radius because its scale is exactly the size you pass.

## The loop that keeps markers cheap

A single `DrawMarker` call is cheap. The expensive part is scripts that loop over every configured location every frame, doing distance maths and drawing markers the player cannot possibly see. The fix is a two-speed loop: check distances once a second, and only run per-frame drawing while something is close.

*client.lua*

```lua
local POINTS = {
    { coords = vector3(215.8, -810.1, 30.7), label = 'Garage' },
    { coords = vector3(-47.2, -1757.5, 29.4), label = 'Shop' },
}
local DRAW_DISTANCE = 25.0
local USE_DISTANCE = 1.5

CreateThread(function()
    while true do
        local sleep = 1000
        local pos = GetEntityCoords(PlayerPedId())

        for _, point in ipairs(POINTS) do
            local dist = #(pos - point.coords)
            if dist < DRAW_DISTANCE then
                sleep = 0
                DrawMarker(1, point.coords.x, point.coords.y, point.coords.z - 1.0,
                    0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                    1.5, 1.5, 0.6, 40, 130, 255, 140,
                    false, false, 2, false, nil, nil, false)

                if dist < USE_DISTANCE and IsControlJustReleased(0, 38) then
                    TriggerEvent('myresource:use', point.label)
                end
            end
        end

        Wait(sleep)
    end
end)
```

With nothing nearby the thread wakes once a second and does a few vector subtractions, which does not register in the resource monitor. Near a marker it runs every frame, which is unavoidable because the native only draws for one frame. Control 38 is the E key (`INPUT_PICKUP`).

> **Many points?** — With hundreds of points, split the check: every second, build a short list of points within 50 m, and let the per-frame loop draw only that list. The distance check against the full list then runs once a second instead of every frame.

## Placing ground markers correctly

Coordinates copied from a player position are at the ped's centre, roughly one metre above the ground. Ground markers drawn there float at knee height. Subtract about 1.0 from z for markers of type 1, 25 and 27, or find the real ground height once and cache it:

*client.lua*

```lua
local function groundZ(coords)
    local found, z = GetGroundZFor_3dCoord(coords.x, coords.y, coords.z + 2.0, false)
    return found and z or (coords.z - 1.0)
end
```

Only call the ground lookup once per point and store the result. It needs the collision around the point to be loaded, so run it when the player is near, not at resource start for every point on the map.

## Custom texture markers

Marker types 8 and 9 are flat planes that normally show the Lost MC logo. Pass a texture dictionary and texture name and they draw your image instead, which is how servers put their logo on the floor of a garage or a job icon above a door.

*client.lua — logo on the floor*

```lua
local DICT, TEX = 'my_markers', 'garage_logo'

CreateThread(function()
    RequestStreamedTextureDict(DICT, false)
    while not HasStreamedTextureDictLoaded(DICT) do Wait(0) end
end)

local function drawLogo(coords)
    DrawMarker(9, coords.x, coords.y, coords.z - 0.97,
        0.0, 0.0, 0.0, 90.0, 0.0, 0.0,
        2.0, 2.0, 2.0, 255, 255, 255, 220,
        false, false, 2, false, DICT, TEX, false)
end
```

The image lives in `stream/my_markers.ytd`. Keep it small, 256 × 256 or 512 × 512 with an alpha channel; a 4K logo under every garage adds up in texture memory for no visible gain. Rotating 90 degrees on X lays the plane flat on the ground; with zero rotation and `faceCamera` set to true it floats like a sign. For ideas on texture budgets, see [texture optimisation](https://fam-tools.com/guides/fivem-texture-optimization).

## Colour, size and visibility conventions

Markers are part of your server's visual language. Players learn quickly that a blue cylinder means "press E here", so keep the meaning consistent across every resource you install. Mixed conventions from different script authors are one of the things that make a server feel assembled rather than designed.

| Purpose | Suggested type | Colour | Notes |
| --- | --- | --- | --- |
| Interaction point (shops, lockers) | 27 or 25 | Server accent | Flat on the ground, alpha ~150 |
| Vehicle spawn or return | 36 | Blue or green | Face camera, slight bob |
| Job pickup above an object | 2 or 20 | Yellow | Rotate on, bob on |
| Danger or restricted | 1 | Red | Taller cylinder, low alpha |
| Money or payouts | 29 | Green | Rotate on |

- Keep alpha below about 180 so the ground texture still shows through ground markers.
- Use the same scale for the same purpose everywhere; a 3 m ring at one shop and a 1 m ring at the next reads as two different things.
- Hide markers while the player is in a vehicle if the point is for players on foot, and vice versa.
- Do not draw markers through walls into interiors the player is not in; check the interior with `GetInteriorFromEntity` if points sit inside MLOs.

## Common mistakes

| Mistake | Effect | Fix |
| --- | --- | --- |
| Drawing all markers every frame, map-wide | Measurable CPU time for nothing | Distance check with a sleeping loop |
| `Wait(1)` or `Wait(5)` in the draw loop | Markers flicker | `Wait(0)` while drawing |
| Using the player z for ground markers | Rings float at knee height | Subtract about 1.0 or cache the ground z |
| Using `IsControlPressed` | Action fires many times per press | `IsControlJustReleased` |
| Requesting the texture dict every frame | Streaming churn | Request once, then draw |

## Markers, checkpoints or target systems

| Tool | Best for | Cost |
| --- | --- | --- |
| `DrawMarker` | Visible interaction points, ground circles | Per frame while near |
| `CreateCheckpoint` | Race checkpoints with arrows and numbers | Created once, drawn by the game |
| Target / eye systems | Interacting with props, peds and doors | Raycast while the key is held |
| 3D text or NUI prompts | Explaining what a point does | Per frame while near |

Checkpoints are created once with `CreateCheckpoint` and removed with `DeleteCheckpoint`; do not create them every frame the way you draw markers. Many modern servers replace floor markers with a target system for immersion, but markers still win for spots players need to find from a distance, such as garages and job starts. Their map counterpart is a blip, covered in [the blips guide](https://fam-tools.com/guides/fivem-blips-guide).

## Questions

### Why does my marker only flash for one frame?

`DrawMarker` draws for a single frame. Call it inside a loop with `Wait(0)` while the marker should be visible.

### What marker type is the classic ground circle?

Type 1, the vertical cylinder, with a short z scale. Types 25 and 27 are flat ground rings.

### Why is my marker floating above the ground?

Player coordinates are about a metre above the ground. Subtract roughly 1.0 from z, or use `GetGroundZFor_3dCoord` once and cache it.

### How do I use my own image as a marker?

Stream a .ytd, load it with `RequestStreamedTextureDict`, and pass its dictionary and texture name to `DrawMarker` with type 8 or 9.

### Do markers hurt FPS?

Only when scripts draw many of them every frame regardless of distance. Draw only nearby markers and sleep the loop otherwise.

## Related

- https://fam-tools.com/guides/fivem-blips-guide
- https://fam-tools.com/guides/fivem-client-fps-optimization
- https://fam-tools.com/guides/fivem-server-performance
- https://fam-tools.com/guides/fivem-texture-optimization
