Discord Text-Based Progress Bars

Render percentage bars in Discord messages using Unicode block characters inside a monospace code block. Works in any Discord client since it requires no special rendering.

Why / When to Use

When displaying progress, usage, or health metrics in a Discord bot message and you need a visual bar without image attachments. Pairs well with ANSI color labels.

Core Concept / Commands

Two key Unicode characters:

  • (U+2588) — filled block
  • (U+2591) — light shade (empty)

Formula (10-block bar)

def make_bar(pct: int, width: int = 10) -> str:
    filled = round(pct / 100 * width)
    empty = width - filled
    return "█" * filled + "░" * empty
 
# Usage
bar = make_bar(80)   # → "████████░░"

Aligned multi-metric display

Wrap in a triple-backtick code block for monospace alignment:

CPU  [████████░░] 80%
RAM  [█████░░░░░] 50%
DISK [███░░░░░░░] 30%

Python to generate:

metrics = [("CPU", 80), ("RAM", 50), ("DISK", 30)]
lines = [f"{label:<5}[{make_bar(pct)}] {pct}%" for label, pct in metrics]
message = "```\n" + "\n".join(lines) + "\n```"

Key Options / Variants

StyleExample
Brackets[████████░░] 80%
Pipe|████████░░| 80%
Label + barCPU [████████░░] 80%

Gotchas

  • Must use a triple-backtick code block to force monospace font; otherwise characters won’t align.
  • round() can cause minor off-by-one for some percentages — acceptable for display purposes.
  • Emoji (🔴🟡🟢) can be combined outside the bar for quick color-coded severity.

Source

Conversation: “Text-based percentage bars for Discord” — 2026-05-17

Updates — 2026-05-17

Self-contained build_bar variant (includes brackets + percentage label)

The build_bar function below returns the full formatted string including brackets and percentage — drop it directly into an f-string without extra formatting:

def build_bar(percentage: float, width: int = 10) -> str:
    filled = round(percentage / 100 * width)
    empty = width - filled
    return f"[{'█' * filled}{'░' * empty}] {percentage:.0f}%"
 
# Usage in a Discord message line:
token_indicator = '🔴' if token_pct >= 80 else '🟡' if token_pct >= 50 else '🟢'
lines = [
    f"**Token Usage:** {token_indicator} {build_bar(token_pct)} of {token_cap} tokens",
    f"**Reset:** ⏰ __***{format_reset(token_reset)}***__",
]

Output: **Token Usage:** 🟡 [█████░░░░░] 50% of 5000 tokens

Use build_bar when the bar and percentage belong together on one line. Use make_bar (core concept above) when you need the raw block string for custom placement.