Quick Answer
Your add-on causes extreme lag, FPS drops, or world freezes because of runaway script loops (executing every tick), entity spam from uncontrolled spawning, high-resolution textures without mipmaps, particle effect overload, or overly complex Molang expressions. The fix: add tick throttling to scripts, limit entity counts, use 16x/32x textures with mipmaps, cap particle counts, and simplify Molang math.
Top 5 Performance Killers (July 2026)
- Runaway Script Loops: Code in
system.runTick()orworld.beforeEvents.worldTickwithout throttling runs 20x/second — destroys performance. - Entity Spam: Spawning entities in loops without limits (e.g., particle entities, projectile spam) crashes servers/clients.
- High-Res Textures Without Mipmaps: 512px+ textures on mobile/Switch eat VRAM; missing mipmaps cause texture thrashing.
- Particle Effect Overload:
minecraft:particle_effectcomponents with highmax_particlesor frequent triggers. - Complex Molang in Animations/Render Controllers: Math-heavy expressions (trig, noise, many conditionals) evaluated per-vertex/frame.
Step-by-Step Fixes
1. Throttle Script Execution (Critical)
Bad (runs every tick):
import { system, world } from "@minecraft/server";
system.runTick(() => {
// This runs 20 times/second — LAG!
const players = world.getPlayers();
players.forEach(p => { /* heavy logic */ });
});
Good (throttled to every 20 ticks = 1 second):
import { system, world } from "@minecraft/server";
let tickCounter = 0;
system.runTick(() => {
tickCounter++;
if (tickCounter % 20 !== 0) return; // Run once per second
const players = world.getPlayers();
players.forEach(p => { /* heavy logic */ });
});
Better: Use system.runInterval (v26.0+):
import { system, world } from "@minecraft/server";
system.runInterval(() => {
const players = world.getPlayers();
players.forEach(p => { /* heavy logic */ });
}, 20); // 20 ticks = 1 second
2. Limit Entity Spawns
Always cap entity counts and clean up:
import { world, system } from "@minecraft/server";
const MAX_ENTITIES = 50;
let activeEntities = [];
function spawnParticleEffect(location) {
if (activeEntities.length >= MAX_ENTITIES) {
// Remove oldest
const old = activeEntities.shift();
if (old?.isValid) old.remove();
}
const entity = world.spawnEntity("minecraft:glow_particle", location);
activeEntities.push(entity);
// Auto-cleanup after 5 seconds
system.runTimeout(() => {
if (entity.isValid) entity.remove();
activeEntities = activeEntities.filter(e => e !== entity);
}, 100); // 100 ticks = 5 seconds
}
3. Optimize Textures
| Platform | Max Recommended Resolution | Mipmaps Required? |
|---|---|---|
| Windows 10/11 (High-end) | 512×512 | Yes |
| Windows 10/11 (Mid-range) | 256×256 | Yes |
| iOS / Android (Modern) | 128×128 | Yes |
| iOS / Android (Older) | 64×64 | Yes |
| Nintendo Switch | 64×64 | Yes |
| Xbox / PS5 | 256×256 | Yes |
Add mipmaps in manifest.json texture entry:
"texture_data": {
"my_texture": {
"textures": "textures/blocks/my_block",
"filter": "linear_mipmap_linear"
}
}
4. Cap Particle Effects
// In entity JSON - limit particle count
"minecraft:particle_effect": {
"effect": "my_custom_particle",
"max_particles": 20, // Never exceed 50 per entity
"lifetime": 1.0
}
5. Simplify Molang Expressions
Heavy (per-vertex):
"scale": "Math.sin(query.life_time * 20) * 0.5 + 1.0"
Light (pre-compute in script, pass as variable):
// Script (runs once per second)
system.runInterval(() => {
const scale = Math.sin(Date.now() / 1000 * 20) * 0.5 + 1.0;
entity.setProperty("custom:scale", scale);
}, 20);
// Render controller (just reads variable)
"scale": "query.custom:scale"
Profiling: How to Find the Bottleneck
- Windows 10/11: Press F3 + L for profiler overlay; check “Script” and “Render” times.
- All Platforms: Check
content_log.txtfor[Script] Warning: Long running script detected. - Realms: Use
/script watchdogcommand to see script execution times.
Still Lagging?
Disable add-ons one by one to isolate the culprit. Also see our guides: v26.0+ Breaking Changes and Import Issues.
Updated for Minecraft Bedrock 1.21.20+ (v26.0/v26.2), July 2026.
