{"id":219,"date":"2026-10-18T18:01:33","date_gmt":"2026-10-18T18:01:33","guid":{"rendered":"https:\/\/devdojo.co.in\/?p=219"},"modified":"2026-10-18T18:01:34","modified_gmt":"2026-10-18T18:01:34","slug":"genai-series-part-2-tokens-context-window-parameters","status":"publish","type":"post","link":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/","title":{"rendered":"Generative AI Part 2: Tokens, Context Windows and Model Parameters"},"content":{"rendered":"\n<div class=\"dd-post\">\n<style>\n.single article:has(.dd-hero) .entry-media{display:none}\n.dd-post{--navy:#0b1020;--blue:#3178c6;--violet:#7c5cff;--ink:#1f2433;--muted:#5b6275;--line:#e3e6ef;font-size:17px;line-height:1.75;color:var(--ink)}\n.dd-post h2{margin:2.2em 0 .6em;font-size:1.6em;line-height:1.3;scroll-margin-top:90px}\n.dd-post h3{margin:1.6em 0 .5em;font-size:1.22em;scroll-margin-top:90px}\n.dd-post a{color:var(--blue);text-decoration:underline;text-underline-offset:3px}\n.dd-post pre{background:#0f1430;color:#e6e9f5;padding:18px 20px;border-radius:12px;overflow-x:auto;line-height:1.6;border:1px solid #232a52;margin:1.2em 0;font-size:14.5px !important}\n.dd-post pre code{font-size:1em !important;background:none;color:inherit;padding:0;font-family:\"JetBrains Mono\",\"Fira Code\",Consolas,Menlo,monospace;white-space:pre}\n.dd-post :not(pre)>code{background:#eef1fb;color:#2b3a8f;padding:2px 6px;border-radius:5px;font-size:.9em}\n.dd-post .dd-file{display:inline-block;background:#151b3b;color:#c9d1ff;font:600 13px\/1 \"JetBrains Mono\",Consolas,monospace;padding:7px 12px;border-radius:8px 8px 0 0;margin:1em 0 -1.2em;position:relative}\n.dd-post .dd-hero{margin:0 0 1.6em;border-radius:16px;overflow:hidden;box-shadow:0 10px 30px rgba(11,16,32,.25)}\n.dd-post .dd-hero svg{display:block;width:100%;height:auto}\n.dd-post .dd-hero .node{transition:transform .25s,filter .25s;transform-box:fill-box;transform-origin:center;cursor:pointer}\n.dd-post .dd-hero .node:hover{transform:scale(1.08);filter:drop-shadow(0 0 10px #7c5cff)}\n.dd-post .dd-series{display:inline-flex;align-items:center;gap:8px;background:#151b3b;color:#dfe3ff;border-radius:999px;padding:6px 14px;font-size:.88em;font-weight:600;margin:0 0 .8em}\n.dd-post .dd-series span{background:var(--violet);color:#fff;border-radius:999px;padding:2px 10px}\n.dd-post .dd-prereq{font-size:.96em;color:var(--muted);border-left:3px solid var(--line);padding-left:12px;margin:.6em 0 1.2em}\n.dd-post .dd-summary{background:linear-gradient(135deg,#eef3ff,#f4efff);border:1px solid #d6dcf5;border-left:5px solid var(--violet);border-radius:12px;padding:18px 22px;margin:1.4em 0}\n.dd-post .dd-summary strong.lbl{display:block;font-size:1.05em;margin-bottom:6px;color:#3a2fa0}\n.dd-post .dd-summary ul{margin:.3em 0 0 1.1em}\n.dd-post .dd-toc{background:#f8f9fc;border:1px solid var(--line);border-radius:12px;padding:16px 22px;margin:1.4em 0}\n.dd-post .dd-toc ol{margin:.4em 0 0 1.2em;columns:2;column-gap:28px}\n.dd-post .dd-toc li{break-inside:avoid;margin:.15em 0}\n@media(max-width:640px){.dd-post .dd-toc ol{columns:1}}\n.dd-post .dd-tip,.dd-post .dd-note,.dd-post .dd-warn{border-radius:10px;padding:14px 18px;margin:1.3em 0}\n.dd-post .dd-tip{background:#ecfbf3;border-left:4px solid #1f9d61}\n.dd-post .dd-note{background:#eef4ff;border-left:4px solid var(--blue)}\n.dd-post .dd-warn{background:#fff6e8;border-left:4px solid #e08a00}\n.dd-post .dd-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px;margin:1.3em 0}\n.dd-post .dd-card{border:1px solid var(--line);border-radius:12px;padding:14px 16px;background:#fff;box-shadow:0 2px 8px rgba(20,30,70,.05)}\n.dd-post .dd-card b{display:block;color:#3a2fa0;margin-bottom:4px}\n.dd-post table{width:100%;border-collapse:collapse;margin:1.3em 0;font-size:.95em}\n.dd-post th,.dd-post td{border:1px solid var(--line);padding:10px 12px;text-align:left;vertical-align:top}\n.dd-post th{background:#151b3b;color:#fff}\n.dd-post tr:nth-child(even) td{background:#f8f9fc}\n.dd-post .dd-tablewrap{overflow-x:auto}\n.dd-post figure{margin:1.6em 0;text-align:center}\n.dd-post figure svg{width:100%;height:auto;border-radius:12px}\n.dd-post figcaption{font-size:.9em;color:var(--muted);margin-top:8px}\n.dd-post details{border:1px solid var(--line);border-radius:10px;padding:12px 16px;margin:.7em 0;background:#fff}\n.dd-post details summary{cursor:pointer;font-weight:600}\n.dd-post details[open] summary{margin-bottom:8px;color:#3a2fa0}\n.dd-post .dd-roadmap{border:2px solid #d6dcf5;background:#fbfbff}\n.dd-post .dd-roadmap h4{margin:1em 0 .3em;color:#151b3b;font-size:1em;text-transform:uppercase;letter-spacing:.04em}\n.dd-post .dd-roadmap ol{margin:.2em 0 .6em 1.4em;padding:0}\n.dd-post .dd-roadmap li{margin:.2em 0}\n.dd-post .dd-roadmap .here{background:var(--violet);color:#fff;border-radius:999px;padding:1px 9px;font-size:.8em;font-weight:700;margin-left:6px}\n.dd-post .dd-roadmap .soon{color:#8a90a6;font-size:.82em;margin-left:6px}\n.dd-post .dd-tabs{border:1px solid var(--line);border-radius:12px;padding:6px 16px 16px;margin:1.4em 0;background:#fbfbfe}\n.dd-post .dd-tabs>input{position:absolute;opacity:0;pointer-events:none}\n.dd-post .dd-tabs .labels label{display:inline-block;padding:8px 16px;margin:10px 6px 0 0;border-radius:999px;border:1px solid #cfd5ea;cursor:pointer;font-weight:600;font-size:.95em;background:#fff;transition:background .2s}\n.dd-post .dd-tabs .labels label:hover{border-color:var(--violet)}\n.dd-post .dd-tabs .panel{display:none;margin-top:12px}\n.dd-post .dd-tabs #ti1:checked~.labels label[for=ti1],.dd-post .dd-tabs #ti2:checked~.labels label[for=ti2],.dd-post .dd-tabs #ti3:checked~.labels label[for=ti3],.dd-post .dd-tabs #ti4:checked~.labels label[for=ti4]{background:var(--violet);color:#fff;border-color:var(--violet)}\n.dd-post .dd-tabs #ti1:checked~.p1,.dd-post .dd-tabs #ti2:checked~.p2,.dd-post .dd-tabs #ti3:checked~.p3,.dd-post .dd-tabs #ti4:checked~.p4{display:block}\n.dd-post .dd-tabs #ti1:focus-visible~.labels label[for=ti1],.dd-post .dd-tabs #ti2:focus-visible~.labels label[for=ti2],.dd-post .dd-tabs #ti3:focus-visible~.labels label[for=ti3],.dd-post .dd-tabs #ti4:focus-visible~.labels label[for=ti4]{outline:2px solid var(--blue);outline-offset:2px}\n.dd-post .dd-cta{background:linear-gradient(135deg,#0b1020,#151b3b);color:#e8ebff;border-radius:16px;padding:24px 26px;margin:2em 0;text-align:center}\n.dd-post .dd-cta h3{color:#fff;margin-top:0}\n.dd-post .dd-cta a{color:#a99bff}\n.dd-post .dd-vsc{position:relative;margin:1.5em 0;border-radius:12px;overflow:hidden;background:#1e1e1e;border:1px solid #2b2b2b;box-shadow:0 14px 34px rgba(0,0,0,.28);font-family:\"Segoe UI\",system-ui,sans-serif}\n.dd-post .dd-vsc>input{position:absolute;opacity:0;pointer-events:none}\n.dd-post .dd-vsc-bar{display:flex;align-items:center;gap:12px;background:#323233;color:#cccccc;font-size:12.5px;padding:8px 12px}\n.dd-post .dd-dots{display:inline-flex;gap:7px}.dd-post .dd-dots i{width:12px;height:12px;border-radius:50%;background:#ff5f57;display:block}.dd-post .dd-dots i:nth-child(2){background:#febc2e}.dd-post .dd-dots i:nth-child(3){background:#28c840}\n.dd-post .dd-vsc-title{flex:1;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-right:50px;opacity:.85}\n.dd-post .dd-vsc-tabs{display:flex;align-items:stretch;background:#252526;border-bottom:1px solid #1e1e1e;overflow-x:auto}\n.dd-post .dd-vsc-tabs label{display:flex;align-items:center;gap:7px;padding:9px 16px;color:#969696;font-size:13px;cursor:pointer;background:#2d2d2d;border-right:1px solid #252526;border-top:1px solid transparent;white-space:nowrap;margin:0;transition:color .15s}\n.dd-post .dd-vsc-tabs label:hover{color:#e0e0e0}\n.dd-post .dd-vsc-tabs .ic{font:700 9.5px\/1 Consolas,monospace;padding:3px 4px;border-radius:3px;color:#1e1e1e}\n.dd-post .ic.py{background:#ffd43b}.dd-post .ic.js{background:#f1e05a}.dd-post .ic.sh{background:#89e051}\n.dd-post .dd-vsc-tabs label.run{margin-left:auto;background:transparent;border:0;color:#89d185;font-weight:600;display:none}\n.dd-post .dd-vsc-tabs label.run:hover{color:#b5f0b0;background:#2a2d2e}\n.dd-post .dd-vsc-pane{display:none}\n.dd-post .dd-vsc>.f1:checked~.dd-vsc-tabs .t1,.dd-post .dd-vsc>.f2:checked~.dd-vsc-tabs .t2,.dd-post .dd-vsc>.f3:checked~.dd-vsc-tabs .t3{background:#1e1e1e;color:#ffffff;border-top-color:#3178c6}\n.dd-post .dd-vsc>.f1:checked~.p1,.dd-post .dd-vsc>.f2:checked~.p2,.dd-post .dd-vsc>.f3:checked~.p3{display:block}\n.dd-post .dd-vsc>.f1:checked~.dd-vsc-tabs .run1,.dd-post .dd-vsc>.f2:checked~.dd-vsc-tabs .run2,.dd-post .dd-vsc>.f3:checked~.dd-vsc-tabs .run3{display:flex}\n.dd-post .dd-vsc>.f1:focus-visible~.dd-vsc-tabs .t1,.dd-post .dd-vsc>.f2:focus-visible~.dd-vsc-tabs .t2,.dd-post .dd-vsc>.f3:focus-visible~.dd-vsc-tabs .t3,.dd-post .dd-vsc>input[type=checkbox]:focus-visible~.dd-vsc-tabs .run{outline:2px solid #3178c6;outline-offset:-2px}\n.dd-post .dd-vsc-crumbs{background:#1e1e1e;color:#a9a9a9;font-size:12px;padding:5px 16px 2px}\n.dd-post .dd-vsc pre.dd-vsc-code{background:#1e1e1e;color:#d4d4d4;border:0;border-radius:0;margin:0;padding:8px 0 14px;counter-reset:ln;line-height:1.62;overflow-x:auto}\n.dd-post .dd-vsc pre code{font-family:Consolas,\"JetBrains Mono\",\"Fira Code\",Menlo,monospace;color:inherit;background:none;white-space:pre}\n.dd-post .dd-vsc .l{display:inline-block;min-width:100%;padding-right:18px;box-sizing:border-box}\n.dd-post .dd-vsc .l::before{counter-increment:ln;content:counter(ln);display:inline-block;width:3.2em;padding-right:1.4em;text-align:right;color:#6e7681;user-select:none;-webkit-user-select:none}\n.dd-post .dd-vsc .l:hover{background:#2a2d2e}.dd-post .dd-vsc .l:hover::before{color:#c6c6c6}\n.dd-post .dd-vsc .k,.dd-post .dd-vsc .kn{color:#c586c0}.dd-post .dd-vsc .kc{color:#569cd6}.dd-post .dd-vsc .s{color:#ce9178}.dd-post .dd-vsc .c{color:#6a9955}.dd-post .dd-vsc .m{color:#b5cea8}.dd-post .dd-vsc .nf{color:#dcdcaa}.dd-post .dd-vsc .nc{color:#4ec9b0}.dd-post .dd-vsc .nb{color:#4ec9b0}.dd-post .dd-vsc .nd{color:#dcdcaa}.dd-post .dd-vsc .n{color:#9cdcfe}.dd-post .dd-vsc .o{color:#d4d4d4}.dd-post .dd-vsc .gp{color:#89d185;user-select:none;-webkit-user-select:none}\n.dd-post .dd-vsc-term{display:none;border-top:1px solid #3c3c3c;background:#181818}\n.dd-post .dd-vsc>.r1:checked~.p1 .dd-vsc-term,.dd-post .dd-vsc>.r2:checked~.p2 .dd-vsc-term,.dd-post .dd-vsc>.r3:checked~.p3 .dd-vsc-term{display:block;animation:ddterm .35s ease-out}\n@keyframes ddterm{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}\n.dd-post .dd-term-head{display:flex;gap:18px;align-items:center;font-size:11px;letter-spacing:.06em;color:#8b8b8b;padding:7px 16px 0}\n.dd-post .dd-term-head span:first-child{color:#e7e7e7;border-bottom:1px solid #e7e7e7;padding-bottom:4px}\n.dd-post .dd-term-head .dd-term-note{margin-left:auto;letter-spacing:0;text-transform:none;color:#d7ba7d;border:0;font-size:11.5px}\n.dd-post .dd-vsc-term pre{background:#181818;color:#cccccc;border:0;margin:0;padding:10px 16px 14px;border-radius:0}\n.dd-post .dd-vsc-status{display:flex;flex-wrap:wrap;gap:4px 14px;background:#007acc;color:#fff;font-size:11.5px;padding:4px 12px}\n.dd-post .dd-vsc-status .sp{flex:1}\n.dd-post .dd-vsc-termonly pre.dd-vsc-code{background:#181818;padding:12px 16px}\n@media(max-width:640px){.dd-post .dd-vsc-title{padding-right:0;text-align:left}.dd-post .dd-vsc-status span:nth-child(n+4){display:none}.dd-post .dd-vsc .l::before{width:2.2em;padding-right:1em}}\n.dd-post .dd-vsc-hint{font-size:.93em;color:var(--muted);margin-top:-.6em}\n.dd-post .dd-next{border:1px dashed var(--violet);border-radius:12px;padding:16px 20px;margin:1.6em 0;background:#f7f4ff}\n<\/style>\n\n<div class=\"dd-hero\">\n<svg viewBox=\"0 0 1200 520\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" role=\"img\" aria-label=\"Generative AI series Part 2 banner: text is split into tokens, tokens fill the context window, and the model's parameters process them\">\n<defs>\n<linearGradient id=\"ddbg\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\"><stop offset=\"0\" stop-color=\"#0b1020\"\/><stop offset=\"1\" stop-color=\"#151b3b\"\/><\/linearGradient>\n<linearGradient id=\"ddac\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"0\"><stop offset=\"0\" stop-color=\"#3178c6\"\/><stop offset=\"1\" stop-color=\"#7c5cff\"\/><\/linearGradient>\n<radialGradient id=\"ddglow\" cx=\".5\" cy=\".5\" r=\".5\"><stop offset=\"0\" stop-color=\"#7c5cff\" stop-opacity=\".45\"\/><stop offset=\"1\" stop-color=\"#7c5cff\" stop-opacity=\"0\"\/><\/radialGradient>\n<\/defs>\n<rect x=\"0\" y=\"-60\" width=\"1200\" height=\"640\" fill=\"url(#ddbg)\"\/>\n<circle cx=\"1000\" cy=\"110\" r=\"250\" fill=\"url(#ddglow)\"\/>\n<g opacity=\".12\" stroke=\"#9fb2ff\"><path d=\"M0 100H1200M0 200H1200M0 300H1200M0 400H1200M200 0V520M400 0V520M600 0V520M800 0V520M1000 0V520\"\/><\/g>\n<rect x=\"60\" y=\"46\" width=\"128\" height=\"38\" rx=\"19\" fill=\"url(#ddac)\"\/>\n<text x=\"124\" y=\"71\" text-anchor=\"middle\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"18\" font-weight=\"700\" fill=\"#fff\">PART 2<\/text>\n<text x=\"204\" y=\"71\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"18\" fill=\"#aab4e8\">Generative AI Series \u00b7 DevDojo<\/text>\n<text x=\"60\" y=\"148\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"50\" font-weight=\"800\" fill=\"#ffffff\">Tokens, Context Windows<\/text>\n<text x=\"60\" y=\"204\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"50\" font-weight=\"800\" fill=\"#ffffff\">and Model Parameters<\/text>\n<text x=\"60\" y=\"248\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"24\" fill=\"#c9d1ff\">What an LLM reads, how much it can hold, and what &#8220;8B&#8221; really means<\/text>\n<path id=\"ddflow\" d=\"M155 395 C 260 345, 330 445, 430 395 S 620 345, 720 395 S 930 445, 1050 395\" fill=\"none\" stroke=\"url(#ddac)\" stroke-width=\"3\" stroke-dasharray=\"8 8\" opacity=\".8\"\/>\n<g class=\"node\"><rect x=\"80\" y=\"360\" width=\"150\" height=\"70\" rx=\"14\" fill=\"#1b2250\" stroke=\"#3178c6\" stroke-width=\"2\"\/><text x=\"155\" y=\"392\" text-anchor=\"middle\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"20\" font-weight=\"700\" fill=\"#fff\">Text<\/text><text x=\"155\" y=\"415\" text-anchor=\"middle\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"14\" fill=\"#9fb2ff\">&#8220;Tokenization&#8221;<\/text><\/g>\n<g class=\"node\"><rect x=\"345\" y=\"360\" width=\"170\" height=\"70\" rx=\"14\" fill=\"#1b2250\" stroke=\"#3178c6\" stroke-width=\"2\"\/><text x=\"430\" y=\"392\" text-anchor=\"middle\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"20\" font-weight=\"700\" fill=\"#fff\">Tokens<\/text><text x=\"430\" y=\"415\" text-anchor=\"middle\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"14\" fill=\"#9fb2ff\">&#8220;Token&#8221; + &#8220;ization&#8221;<\/text><\/g>\n<g class=\"node\"><rect x=\"620\" y=\"345\" width=\"200\" height=\"100\" rx=\"16\" fill=\"#1b2250\" stroke=\"#7c5cff\" stroke-width=\"2\"\/><text x=\"720\" y=\"380\" text-anchor=\"middle\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"20\" font-weight=\"700\" fill=\"#fff\">Context window<\/text><rect x=\"645\" y=\"397\" width=\"150\" height=\"16\" rx=\"8\" fill=\"#0b1020\"\/><rect x=\"645\" y=\"397\" width=\"105\" height=\"16\" rx=\"8\" fill=\"url(#ddac)\"\/><text x=\"720\" y=\"433\" text-anchor=\"middle\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"13\" fill=\"#9fb2ff\">70% used<\/text><\/g>\n<g class=\"node\"><rect x=\"960\" y=\"340\" width=\"180\" height=\"110\" rx=\"18\" fill=\"url(#ddac)\"\/><text x=\"1050\" y=\"385\" text-anchor=\"middle\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"26\" font-weight=\"800\" fill=\"#fff\">LLM<\/text><text x=\"1050\" y=\"412\" text-anchor=\"middle\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"15\" fill=\"#eef\">8B parameters<\/text><text x=\"1050\" y=\"432\" text-anchor=\"middle\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"13\" fill=\"#eef\">(learned weights)<\/text><\/g>\n<circle r=\"7\" fill=\"#7c5cff\"><animateMotion dur=\"5s\" repeatCount=\"indefinite\"><mpath href=\"#ddflow\"\/><\/animateMotion><\/circle>\n<circle r=\"5\" fill=\"#3178c6\"><animateMotion dur=\"5s\" begin=\"1.6s\" repeatCount=\"indefinite\"><mpath href=\"#ddflow\"\/><\/animateMotion><\/circle>\n<circle r=\"4\" fill=\"#ffffff\"><animateMotion dur=\"5s\" begin=\"3.2s\" repeatCount=\"indefinite\"><mpath href=\"#ddflow\"\/><\/animateMotion><\/circle>\n<text x=\"60\" y=\"495\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"16\" fill=\"#7f89b5\">devdojo.co.in \u00b7 Beginner friendly \u00b7 Python + Node.js examples<\/text>\n<\/svg>\n<\/div>\n\n<div class=\"dd-series\">Series: Generative AI <span>Part 2 of 30<\/span><\/div>\n<p class=\"dd-prereq\"><strong>What you should know first:<\/strong> read <a href=\"https:\/\/devdojo.co.in\/?p=215\">Generative AI Part 1: What Is Generative AI and How Do LLMs Work?<\/a>. You should know that an LLM writes text by predicting the next token, again and again.<\/p>\n\n<p>Every time you use ChatGPT, Claude or Gemini, three numbers quietly decide what happens: how many <strong>tokens<\/strong> your text becomes, how big the model&#8217;s <strong>context window<\/strong> is, and how many <strong>parameters<\/strong> the model has. They decide your bill, how much text the model can &#8220;see&#8221; at once, why a chatbot forgets the start of a long chat, and whether a model can run on your laptop. In Part 2 of the DevDojo Generative AI series, we explain all three in simple English and write small Python and Node.js programs to measure them yourself.<\/p>\n\n<div class=\"dd-summary\">\n<strong class=\"lbl\">Quick Summary<\/strong>\n<ul>\n<li>A <strong>token<\/strong> is a small piece of text (often part of a word). Models read, think and bill in tokens. In English, 1 token is roughly 4 characters.<\/li>\n<li>The <strong>context window<\/strong> is the model&#8217;s working memory: the maximum number of tokens it can handle in one request, counting <em>both<\/em> your input and its output.<\/li>\n<li><strong>Max output tokens<\/strong> limits how long the answer can be. If it is too small, the answer is cut off.<\/li>\n<li><strong>Parameters<\/strong> are the numbers the model learned during training. &#8220;8B&#8221; means 8 billion of them. More parameters usually means more knowledge, but also more memory and cost.<\/li>\n<li>Count tokens with <code>tiktoken<\/code> \/ <code>js-tiktoken<\/code> or a provider&#8217;s token counting API, and read the <code>usage<\/code> field of every response.<\/li>\n<\/ul>\n<\/div>\n\n<details class=\"dd-roadmap\">\n<summary>Full Generative AI roadmap (30 parts)<\/summary>\n<h4>Beginner<\/h4>\n<ol start=\"1\">\n<li><a href=\"https:\/\/devdojo.co.in\/?p=215\">What Is Generative AI and How Do LLMs Work?<\/a><\/li>\n<li>Tokens, Context Windows and Model Parameters <span class=\"here\">You are here<\/span><\/li>\n<li>Your First LLM API Calls in Python and Node.js (OpenAI, Anthropic, Gemini) <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Prompt Engineering Basics: Roles, Instructions and Examples <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Temperature, Top-p and Controlling Model Output <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Running Open Models Locally with Ollama <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Streaming Responses and Building a Simple Chat UI <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Structured Outputs: Getting Reliable JSON from LLMs <span class=\"soon\">Coming soon<\/span><\/li>\n<\/ol>\n<h4>Intermediate<\/h4>\n<ol start=\"9\">\n<li>Embeddings Explained: Turning Text into Vectors <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Vector Databases: pgvector, Chroma and Pinecone <span class=\"soon\">Coming soon<\/span><\/li>\n<li>RAG Fundamentals: Retrieval-Augmented Generation <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Document Loading and Chunking Strategies <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Better RAG: Hybrid Search, Re-ranking and Query Rewriting <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Function Calling and Tool Use <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Conversation Memory and Long Context Management <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Multimodal AI: Vision, Images and Audio Inputs <span class=\"soon\">Coming soon<\/span><\/li>\n<li>How Image Generation Works: Diffusion Models Basics <span class=\"soon\">Coming soon<\/span><\/li>\n<li>LangChain vs LlamaIndex: When to Use a Framework <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Testing LLM Apps: Evals, Metrics and Test Sets <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Cutting Cost and Latency: Caching, Batching and Model Choice <span class=\"soon\">Coming soon<\/span><\/li>\n<\/ol>\n<h4>Advanced<\/h4>\n<ol start=\"21\">\n<li>Fine-Tuning vs Prompting vs RAG: Choosing the Right Tool <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Fine-Tuning an Open Model with LoRA <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Transformers Deep Dive: Attention Explained Simply <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Reasoning Models and Thinking Time <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Guardrails, Safety and Prompt Injection Defence <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Monitoring and Tracing LLM Apps in Production <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Serving Open Models: vLLM, Quantization and GPUs <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Building a Production GenAI App End to End <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Responsible AI: Privacy, Licensing and Bias <span class=\"soon\">Coming soon<\/span><\/li>\n<li>Final Project: Build Your Own AI Knowledge Assistant <span class=\"soon\">Coming soon<\/span><\/li>\n<\/ol>\n<\/details>\n\n<nav class=\"dd-toc\" aria-label=\"Table of contents\">\n<strong>In this post<\/strong>\n<ol>\n<li><a href=\"#what-is-a-token\">What is a token? (quick recap)<\/a><\/li>\n<li><a href=\"#tokenizers\">How tokenizers split text<\/a><\/li>\n<li><a href=\"#count-tokens\">Count tokens in Python and Node.js<\/a><\/li>\n<li><a href=\"#context-window\">What is a context window?<\/a><\/li>\n<li><a href=\"#input-output\">Input tokens, output tokens and max output<\/a><\/li>\n<li><a href=\"#budget\">Will it fit? A token budget calculator<\/a><\/li>\n<li><a href=\"#long-chats\">Why chatbots forget long chats<\/a><\/li>\n<li><a href=\"#usage\">Read real token usage from an API<\/a><\/li>\n<li><a href=\"#parameters\">What are model parameters?<\/a><\/li>\n<li><a href=\"#comparison\">Tokens vs context vs parameters<\/a><\/li>\n<li><a href=\"#errors\">Common errors and fixes<\/a><\/li>\n<li><a href=\"#best-practices\">Best practices<\/a><\/li>\n<li><a href=\"#practice\">Practice task<\/a><\/li>\n<li><a href=\"#faq\">FAQ<\/a><\/li>\n<\/ol>\n<\/nav>\n<\/div>\n\n\n\n<div class=\"dd-post\">\n<h2 id=\"what-is-a-token\">What is a token? (quick recap)<\/h2>\n<p>In Part 1 we saw that an LLM generates text one <strong>token<\/strong> at a time. A token is a small chunk of text. It can be a whole word (&#8220;cat&#8221;), part of a word (&#8220;ization&#8221;), a space plus a word (&#8221; fun&#8221;), a single punctuation mark (&#8220;!&#8221;) or even part of an emoji.<\/p>\n<p>Why not just use letters or whole words?<\/p>\n<ul>\n<li><strong>Letters<\/strong> would make every sentence very long (more steps for the model, slower and costlier).<\/li>\n<li><strong>Whole words<\/strong> would need a gigantic dictionary and still fail on new words like &#8220;DevDojo&#8221; or a fresh library name.<\/li>\n<li><strong>Sub-word tokens<\/strong> are the middle path: common words stay as one token, and any rare word can still be built from smaller pieces.<\/li>\n<\/ul>\n<figure>\n<svg viewBox=\"0 0 900 300\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" role=\"img\" aria-label=\"Diagram: the sentence 'Tokenization is fun!' is split into tokens and each token becomes a number ID\">\n<rect width=\"900\" height=\"300\" fill=\"#f8f9fc\"\/>\n<text x=\"30\" y=\"40\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"16\" font-weight=\"700\" fill=\"#151b3b\">1. Your text<\/text>\n<rect x=\"30\" y=\"55\" width=\"300\" height=\"46\" rx=\"10\" fill=\"#fff\" stroke=\"#cfd5ea\"\/>\n<text x=\"180\" y=\"85\" text-anchor=\"middle\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"20\" fill=\"#1f2433\">Tokenization is fun!<\/text>\n<path d=\"M340 78 H400\" stroke=\"#7c5cff\" stroke-width=\"3\" marker-end=\"url(#ar1)\"\/>\n<defs><marker id=\"ar1\" markerWidth=\"10\" markerHeight=\"10\" refX=\"8\" refY=\"5\" orient=\"auto\"><path d=\"M0 0L10 5L0 10z\" fill=\"#7c5cff\"\/><\/marker><\/defs>\n<text x=\"410\" y=\"40\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"16\" font-weight=\"700\" fill=\"#151b3b\">2. Tokens (pieces of text)<\/text>\n<g font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"17\">\n<rect x=\"410\" y=\"55\" width=\"80\" height=\"46\" rx=\"10\" fill=\"#e7efff\" stroke=\"#3178c6\"\/><text x=\"450\" y=\"85\" text-anchor=\"middle\" fill=\"#1f2433\">Token<\/text>\n<rect x=\"498\" y=\"55\" width=\"92\" height=\"46\" rx=\"10\" fill=\"#efe9ff\" stroke=\"#7c5cff\"\/><text x=\"544\" y=\"85\" text-anchor=\"middle\" fill=\"#1f2433\">ization<\/text>\n<rect x=\"598\" y=\"55\" width=\"60\" height=\"46\" rx=\"10\" fill=\"#e7efff\" stroke=\"#3178c6\"\/><text x=\"628\" y=\"85\" text-anchor=\"middle\" fill=\"#1f2433\">\u2423is<\/text>\n<rect x=\"666\" y=\"55\" width=\"70\" height=\"46\" rx=\"10\" fill=\"#efe9ff\" stroke=\"#7c5cff\"\/><text x=\"701\" y=\"85\" text-anchor=\"middle\" fill=\"#1f2433\">\u2423fun<\/text>\n<rect x=\"744\" y=\"55\" width=\"44\" height=\"46\" rx=\"10\" fill=\"#e7efff\" stroke=\"#3178c6\"\/><text x=\"766\" y=\"85\" text-anchor=\"middle\" fill=\"#1f2433\">!<\/text>\n<\/g>\n<path d=\"M600 112 V160\" stroke=\"#7c5cff\" stroke-width=\"3\" marker-end=\"url(#ar1)\"\/>\n<text x=\"410\" y=\"190\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"16\" font-weight=\"700\" fill=\"#151b3b\">3. Token IDs (what the model really sees)<\/text>\n<g font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"16\" fill=\"#fff\">\n<rect x=\"410\" y=\"205\" width=\"80\" height=\"44\" rx=\"10\" fill=\"#151b3b\"\/><text x=\"450\" y=\"233\" text-anchor=\"middle\">ID<\/text>\n<rect x=\"498\" y=\"205\" width=\"92\" height=\"44\" rx=\"10\" fill=\"#151b3b\"\/><text x=\"544\" y=\"233\" text-anchor=\"middle\">ID<\/text>\n<rect x=\"598\" y=\"205\" width=\"60\" height=\"44\" rx=\"10\" fill=\"#151b3b\"\/><text x=\"628\" y=\"233\" text-anchor=\"middle\">ID<\/text>\n<rect x=\"666\" y=\"205\" width=\"70\" height=\"44\" rx=\"10\" fill=\"#151b3b\"\/><text x=\"701\" y=\"233\" text-anchor=\"middle\">ID<\/text>\n<rect x=\"744\" y=\"205\" width=\"44\" height=\"44\" rx=\"10\" fill=\"#151b3b\"\/><text x=\"766\" y=\"233\" text-anchor=\"middle\">ID<\/text>\n<\/g>\n<text x=\"30\" y=\"180\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"15\" fill=\"#5b6275\">Common words = 1 token.<\/text>\n<text x=\"30\" y=\"205\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"15\" fill=\"#5b6275\">Rare or long words = several tokens.<\/text>\n<text x=\"30\" y=\"230\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"15\" fill=\"#5b6275\">Spaces usually stick to the next word (\u2423).<\/text>\n<text x=\"30\" y=\"275\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"14\" fill=\"#8a90a6\">Each token maps to one whole-number ID in the tokenizer&#8217;s vocabulary.<\/text>\n<\/svg>\n<figcaption>Figure 1: A tokenizer turns text into pieces, then into number IDs. The model only ever works with those numbers.<\/figcaption>\n<\/figure>\n\n<h2 id=\"tokenizers\">How tokenizers split text (BPE in simple words)<\/h2>\n<p>The program that splits text into tokens is called a <strong>tokenizer<\/strong>. Most modern LLMs use a method called <strong>Byte Pair Encoding (BPE)<\/strong> or a close cousin. The idea is simple:<\/p>\n<ol>\n<li>Start with single bytes (letters, digits, symbols).<\/li>\n<li>Look at a huge amount of training text and find the pair of pieces that appears together most often, for example &#8220;t&#8221; + &#8220;h&#8221;.<\/li>\n<li>Merge that pair into a new piece &#8220;th&#8221; and add it to the vocabulary.<\/li>\n<li>Repeat many thousands of times. Frequent chunks like &#8220;the&#8221;, &#8220;ing&#8221; and &#8221; function&#8221; become single tokens.<\/li>\n<\/ol>\n<p>The final list of pieces is the <strong>vocabulary<\/strong>. Modern vocabularies have from about 100,000 to over 200,000 entries. Each entry has an ID number, and the model only ever sees those numbers.<\/p>\n<div class=\"dd-note\"><strong>Important:<\/strong> every model family has its <em>own<\/em> tokenizer. The same sentence can be 10 tokens for one model and 13 for another. Even newer versions of the same family can change tokenizers, so always count tokens for the exact model you use.<\/div>\n<\/div>\n\n\n\n<div class=\"dd-post\">\n<h2 id=\"count-tokens\">Count tokens in Python and Node.js<\/h2>\n<p>Let&#8217;s measure tokens for real. OpenAI publishes its tokenizer as the open-source <code>tiktoken<\/code> library for Python, and <code>js-tiktoken<\/code> is a JavaScript port. We use the <code>o200k_base<\/code> encoding, which recent OpenAI models use. First install them:<\/p>\n<div class=\"dd-vsc dd-vsc-termonly\" role=\"group\" aria-label=\"Terminal commands to install the tokenizer libraries\">\n<div class=\"dd-vsc-bar\"><span class=\"dd-dots\"><i><\/i><i><\/i><i><\/i><\/span><span class=\"dd-vsc-title\">Terminal \u2014 devdojo-genai<\/span><\/div>\n<pre class=\"dd-vsc-code\"><code><span class=\"c\"># Python<\/span>\n<span class=\"gp\">$<\/span> pip install tiktoken\n<span class=\"c\"># Node.js (pure JavaScript port, no native build needed)<\/span>\n<span class=\"gp\">$<\/span> npm install js-tiktoken<\/code><\/pre>\n<\/div>\n<p>Now count tokens for four kinds of text: plain English, Hindi, a line of code and emojis.<\/p>\n<div class=\"dd-vsc\" role=\"group\" aria-label=\"Code editor: count_tokens.py, count-tokens.mjs\">\n<input type=\"radio\" name=\"v1\" id=\"v1f1\" class=\"f1\" checked>\n<input type=\"radio\" name=\"v1\" id=\"v1f2\" class=\"f2\">\n<input type=\"checkbox\" id=\"v1r1\" class=\"r1\">\n<input type=\"checkbox\" id=\"v1r2\" class=\"r2\">\n<div class=\"dd-vsc-bar\"><span class=\"dd-dots\"><i><\/i><i><\/i><i><\/i><\/span><span class=\"dd-vsc-title\">2 files \u2014 devdojo-genai \u2014 Visual Studio Code<\/span><\/div>\n<div class=\"dd-vsc-tabs\">\n<label for=\"v1f1\" class=\"t1\"><b class=\"ic py\">PY<\/b>count_tokens.py<\/label>\n<label for=\"v1f2\" class=\"t2\"><b class=\"ic js\">JS<\/b>count-tokens.mjs<\/label>\n<label for=\"v1r1\" class=\"run run1\" title=\"Show the output in the terminal\">\u25b6 Run<\/label>\n<label for=\"v1r2\" class=\"run run2\" title=\"Show the output in the terminal\">\u25b6 Run<\/label>\n<\/div>\n<div class=\"dd-vsc-pane p1\">\n<div class=\"dd-vsc-crumbs\">devdojo-genai \u203a count_tokens.py<\/div>\n<pre class=\"dd-vsc-code\"><code><span class=\"l\"><span class=\"c\"># pip install tiktoken<\/span><\/span>\n<span class=\"l\"><span class=\"kn\">import<\/span> <span class=\"n\">tiktoken<\/span><\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"n\">enc<\/span> = <span class=\"n\">tiktoken<\/span>.<span class=\"n\">get_encoding<\/span>(<span class=\"s\">\"o200k_base\"<\/span>)  <span class=\"c\"># tokenizer used by recent OpenAI models<\/span><\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"n\">samples<\/span> = {<\/span>\n<span class=\"l\">    <span class=\"s\">\"english\"<\/span>: <span class=\"s\">\"Generative AI is changing how developers write software.\"<\/span>,<\/span>\n<span class=\"l\">    <span class=\"s\">\"hindi\"<\/span>: <span class=\"s\">\"\u091c\u0928\u0930\u0947\u091f\u093f\u0935 \u090f\u0906\u0908 \u0938\u0949\u092b\u094d\u091f\u0935\u0947\u092f\u0930 \u092c\u0928\u093e\u0928\u0947 \u0915\u093e \u0924\u0930\u0940\u0915\u093e \u092c\u0926\u0932 \u0930\u0939\u093e \u0939\u0948\u0964\"<\/span>,<\/span>\n<span class=\"l\">    <span class=\"s\">\"code\"<\/span>: <span class=\"s\">\"const total = items.reduce((sum, x) =&gt; sum + x.price, 0);\"<\/span>,<\/span>\n<span class=\"l\">    <span class=\"s\">\"emoji\"<\/span>: <span class=\"s\">\"Deploy done! \ud83d\ude80\ud83d\udd25\u2705\"<\/span>,<\/span>\n<span class=\"l\">}<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"k\">for<\/span> <span class=\"n\">name<\/span>, <span class=\"n\">text<\/span> <span class=\"k\">in<\/span> <span class=\"n\">samples<\/span>.<span class=\"n\">items<\/span>():<\/span>\n<span class=\"l\">    <span class=\"n\">ids<\/span> = <span class=\"n\">enc<\/span>.<span class=\"n\">encode<\/span>(<span class=\"n\">text<\/span>)<\/span>\n<span class=\"l\">    <span class=\"n\">ratio<\/span> = <span class=\"nb\">len<\/span>(<span class=\"n\">text<\/span>) \/ <span class=\"nb\">len<\/span>(<span class=\"n\">ids<\/span>)<\/span>\n<span class=\"l\">    <span class=\"nb\">print<\/span>(<span class=\"s\">f\"{<\/span><span class=\"n\">name<\/span><span class=\"s\">:&lt;8} {<\/span><span class=\"nb\">len<\/span>(<span class=\"n\">ids<\/span>)<span class=\"s\">:&gt;3} tokens  {<\/span><span class=\"nb\">len<\/span>(<span class=\"n\">text<\/span>)<span class=\"s\">:&gt;3} chars  {<\/span><span class=\"n\">ratio<\/span><span class=\"s\">:.1f} chars\/token\"<\/span>)<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"n\">pieces<\/span> = [<span class=\"n\">enc<\/span>.<span class=\"n\">decode<\/span>([<span class=\"n\">i<\/span>]) <span class=\"k\">for<\/span> <span class=\"n\">i<\/span> <span class=\"k\">in<\/span> <span class=\"n\">enc<\/span>.<span class=\"n\">encode<\/span>(<span class=\"s\">\"Tokenization\"<\/span>)]<\/span>\n<span class=\"l\"><span class=\"nb\">print<\/span>(<span class=\"s\">\"Tokenization -&gt;\"<\/span>, <span class=\"n\">pieces<\/span>)<\/span><\/code><\/pre>\n<div class=\"dd-vsc-term\"><div class=\"dd-term-head\"><span>TERMINAL<\/span><span>OUTPUT<\/span><span>PROBLEMS<\/span><span class=\"dd-term-note\">Real output \u2013 Python 3, tiktoken<\/span><\/div><pre><code><span class=\"gp\">$<\/span> python count_tokens.py\nenglish   10 tokens   56 chars  5.6 chars\/token\nhindi     16 tokens   48 chars  3.0 chars\/token\ncode      19 tokens   57 chars  3.0 chars\/token\nemoji      7 tokens   16 chars  2.3 chars\/token\nTokenization -&gt; ['Token', 'ization']<\/code><\/pre><\/div>\n<div class=\"dd-vsc-status\"><span>\u2387 main<\/span><span>Ln 19, Col 1<\/span><span class=\"sp\"><\/span><span>Spaces: 4<\/span><span>UTF-8<\/span><span>LF<\/span><span>Python<\/span><\/div>\n<\/div>\n<div class=\"dd-vsc-pane p2\">\n<div class=\"dd-vsc-crumbs\">devdojo-genai \u203a count-tokens.mjs<\/div>\n<pre class=\"dd-vsc-code\"><code><span class=\"l\"><span class=\"c\">\/\/ npm install js-tiktoken<\/span><\/span>\n<span class=\"l\"><span class=\"k\">import<\/span> { <span class=\"n\">getEncoding<\/span> } <span class=\"k\">from<\/span> <span class=\"s\">\"js-tiktoken\"<\/span>;<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"k\">const<\/span> <span class=\"n\">enc<\/span> = <span class=\"n\">getEncoding<\/span>(<span class=\"s\">\"o200k_base\"<\/span>); <span class=\"c\">\/\/ tokenizer used by recent OpenAI models<\/span><\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"k\">const<\/span> <span class=\"n\">samples<\/span> = {<\/span>\n<span class=\"l\">  <span class=\"n\">english<\/span>: <span class=\"s\">\"Generative AI is changing how developers write software.\"<\/span>,<\/span>\n<span class=\"l\">  <span class=\"n\">hindi<\/span>: <span class=\"s\">\"\u091c\u0928\u0930\u0947\u091f\u093f\u0935 \u090f\u0906\u0908 \u0938\u0949\u092b\u094d\u091f\u0935\u0947\u092f\u0930 \u092c\u0928\u093e\u0928\u0947 \u0915\u093e \u0924\u0930\u0940\u0915\u093e \u092c\u0926\u0932 \u0930\u0939\u093e \u0939\u0948\u0964\"<\/span>,<\/span>\n<span class=\"l\">  <span class=\"n\">code<\/span>: <span class=\"s\">\"const total = items.reduce((sum, x) =&gt; sum + x.price, 0);\"<\/span>,<\/span>\n<span class=\"l\">  <span class=\"n\">emoji<\/span>: <span class=\"s\">\"Deploy done! \ud83d\ude80\ud83d\udd25\u2705\"<\/span>,<\/span>\n<span class=\"l\">};<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"k\">for<\/span> (<span class=\"k\">const<\/span> [<span class=\"n\">name<\/span>, <span class=\"n\">text<\/span>] <span class=\"k\">of<\/span> <span class=\"nb\">Object<\/span>.<span class=\"n\">entries<\/span>(<span class=\"n\">samples<\/span>)) {<\/span>\n<span class=\"l\">  <span class=\"k\">const<\/span> <span class=\"n\">ids<\/span> = <span class=\"n\">enc<\/span>.<span class=\"n\">encode<\/span>(<span class=\"n\">text<\/span>);<\/span>\n<span class=\"l\">  <span class=\"k\">const<\/span> <span class=\"n\">ratio<\/span> = (<span class=\"n\">text<\/span>.<span class=\"n\">length<\/span> \/ <span class=\"n\">ids<\/span>.<span class=\"n\">length<\/span>).<span class=\"n\">toFixed<\/span>(<span class=\"m\">1<\/span>);<\/span>\n<span class=\"l\">  <span class=\"n\">console<\/span>.<span class=\"n\">log<\/span>(<span class=\"s\">`${<\/span><span class=\"n\">name<\/span>.<span class=\"n\">padEnd<\/span>(<span class=\"m\">8<\/span>)<span class=\"s\">} ${<\/span><span class=\"nb\">String<\/span>(<span class=\"n\">ids<\/span>.<span class=\"n\">length<\/span>).<span class=\"n\">padStart<\/span>(<span class=\"m\">3<\/span>)<span class=\"s\">} tokens  ${<\/span><span class=\"nb\">String<\/span>(<span class=\"n\">text<\/span>.<span class=\"n\">length<\/span>).<span class=\"n\">padStart<\/span>(<span class=\"m\">3<\/span>)<span class=\"s\">} chars  ${<\/span><span class=\"n\">ratio<\/span><span class=\"s\">} chars\/token`<\/span>);<\/span>\n<span class=\"l\">}<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"k\">const<\/span> <span class=\"n\">pieces<\/span> = <span class=\"n\">enc<\/span>.<span class=\"n\">encode<\/span>(<span class=\"s\">\"Tokenization\"<\/span>).<span class=\"n\">map<\/span>((<span class=\"n\">id<\/span>) =&gt; <span class=\"n\">enc<\/span>.<span class=\"n\">decode<\/span>([<span class=\"n\">id<\/span>]));<\/span>\n<span class=\"l\"><span class=\"n\">console<\/span>.<span class=\"n\">log<\/span>(<span class=\"s\">\"Tokenization -&gt;\"<\/span>, <span class=\"n\">pieces<\/span>);<\/span><\/code><\/pre>\n<div class=\"dd-vsc-term\"><div class=\"dd-term-head\"><span>TERMINAL<\/span><span>OUTPUT<\/span><span>PROBLEMS<\/span><span class=\"dd-term-note\">Real output \u2013 Node.js 22, js-tiktoken<\/span><\/div><pre><code><span class=\"gp\">$<\/span> node count-tokens.mjs\nenglish   10 tokens   56 chars  5.6 chars\/token\nhindi     16 tokens   48 chars  3.0 chars\/token\ncode      19 tokens   57 chars  3.0 chars\/token\nemoji      7 tokens   18 chars  2.6 chars\/token\nTokenization -&gt; [ 'Token', 'ization' ]<\/code><\/pre><\/div>\n<div class=\"dd-vsc-status\"><span>\u2387 main<\/span><span>Ln 20, Col 1<\/span><span class=\"sp\"><\/span><span>Spaces: 2<\/span><span>UTF-8<\/span><span>LF<\/span><span>JavaScript<\/span><\/div>\n<\/div>\n<\/div>\n<p class=\"dd-vsc-hint\">Click the file tabs to switch between Python and Node.js, then press <strong>\u25b6 Run<\/strong> to see the output.<\/p>\n<p>Look closely at the output. It teaches three practical lessons:<\/p>\n<ul>\n<li><strong>English is cheap.<\/strong> About 5\u20136 characters per token here, close to the popular &#8220;1 token \u2248 4 characters \u2248 \u00be of a word&#8221; rule.<\/li>\n<li><strong>Hindi and many other languages cost more.<\/strong> The Hindi sentence is shorter in characters but uses more tokens. If you build apps for Indian users, budget extra tokens for Hindi, Tamil, Telugu and other scripts.<\/li>\n<li><strong>Code and emojis are token-hungry.<\/strong> Symbols like <code>=&gt;<\/code>, brackets and emojis often become separate tokens.<\/li>\n<\/ul>\n<p>Also notice that the two programs report a different <em>character<\/em> count for the emoji line (16 vs 18). That is not a tokenizer difference: Python counts Unicode code points, while JavaScript&#8217;s <code>length<\/code> counts UTF-16 units, and emojis take two units. The token count is the same in both.<\/p>\n<div class=\"dd-tip\"><strong>Tip:<\/strong> want to see tokens visually without code? OpenAI&#8217;s <a href=\"https:\/\/help.openai.com\/en\/articles\/4936856-what-are-tokens-and-how-to-count-them\" target=\"_blank\" rel=\"noopener\">guide to tokens<\/a> links to an online tokenizer where you can paste text and see each token coloured.<\/div>\n<\/div>\n\n\n\n<div class=\"dd-post\">\n<h2 id=\"context-window\">What is a context window in an LLM?<\/h2>\n<p>The <strong>context window<\/strong> is the maximum number of tokens a model can work with in a single request. Think of it as the model&#8217;s <strong>working memory<\/strong> or the size of its desk: everything the model should consider must be on the desk at the same time.<\/p>\n<p>What goes on the desk? More than just your question:<\/p>\n<ul>\n<li>the <strong>system prompt<\/strong> (instructions like &#8220;You are a helpful tutor&#8221;),<\/li>\n<li>the <strong>chat history<\/strong> (every earlier user and assistant message, because the API is stateless and the app re-sends them),<\/li>\n<li>any <strong>documents, search results or tool definitions<\/strong> you add,<\/li>\n<li>your <strong>new message<\/strong>, and<\/li>\n<li>the <strong>answer<\/strong> the model is about to write.<\/li>\n<\/ul>\n<figure>\n<svg viewBox=\"0 0 900 290\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" role=\"img\" aria-label=\"Diagram: a context window bar split into system prompt, chat history, your new message, documents and space reserved for the answer\">\n<rect width=\"900\" height=\"290\" fill=\"#0b1020\"\/>\n<text x=\"30\" y=\"42\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"19\" font-weight=\"700\" fill=\"#fff\">One request = one context window<\/text>\n<text x=\"30\" y=\"68\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"14\" fill=\"#9fb2ff\">Everything below must fit inside the limit, or the request fails (or old messages must be dropped).<\/text>\n<g font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"14\" font-weight=\"700\" fill=\"#fff\">\n<rect x=\"30\" y=\"100\" width=\"90\" height=\"70\" rx=\"10\" fill=\"#3178c6\"\/><text x=\"75\" y=\"140\" text-anchor=\"middle\">System<\/text>\n<rect x=\"126\" y=\"100\" width=\"300\" height=\"70\" rx=\"10\" fill=\"#2b4f8f\"\/><text x=\"276\" y=\"140\" text-anchor=\"middle\">Chat history<\/text>\n<rect x=\"432\" y=\"100\" width=\"190\" height=\"70\" rx=\"10\" fill=\"#5a46c9\"\/><text x=\"527\" y=\"140\" text-anchor=\"middle\">Documents \/ tools<\/text>\n<rect x=\"628\" y=\"100\" width=\"90\" height=\"70\" rx=\"10\" fill=\"#7c5cff\"\/><text x=\"673\" y=\"140\" text-anchor=\"middle\">New msg<\/text>\n<rect x=\"724\" y=\"100\" width=\"146\" height=\"70\" rx=\"10\" fill=\"none\" stroke=\"#28c840\" stroke-width=\"2.5\" stroke-dasharray=\"7 6\"\/><text x=\"797\" y=\"132\" text-anchor=\"middle\" fill=\"#89d185\">Reserved<\/text><text x=\"797\" y=\"152\" text-anchor=\"middle\" fill=\"#89d185\">for answer<\/text>\n<\/g>\n<path d=\"M30 195 H618\" stroke=\"#9fb2ff\" stroke-width=\"2\"\/><path d=\"M30 188 V202 M618 188 V202\" stroke=\"#9fb2ff\" stroke-width=\"2\"\/>\n<text x=\"324\" y=\"222\" text-anchor=\"middle\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"15\" fill=\"#c9d1ff\">input tokens (you pay the input price)<\/text>\n<path d=\"M724 195 H870\" stroke=\"#89d185\" stroke-width=\"2\"\/><path d=\"M724 188 V202 M870 188 V202\" stroke=\"#89d185\" stroke-width=\"2\"\/>\n<text x=\"797\" y=\"222\" text-anchor=\"middle\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"15\" fill=\"#89d185\">output tokens<\/text>\n<text x=\"30\" y=\"266\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"15\" fill=\"#7f89b5\">input tokens + max output tokens  \u2264  context window<\/text>\n<\/svg>\n<figcaption>Figure 2: The context window is shared by everything you send and the answer the model writes back.<\/figcaption>\n<\/figure>\n<p>Context windows have grown fast. Early ChatGPT-era models handled about 4,000 tokens (a few pages). Many current flagship models accept hundreds of thousands of tokens, and several now offer around <strong>1 million tokens<\/strong> \u2013 roughly a few thousand pages of English text. Small open models you run at home often have much smaller windows, and you may set it lower yourself to save memory.<\/p>\n<div class=\"dd-warn\"><strong>Bigger is not always better.<\/strong> A huge context costs more money (you pay for every input token on every request), makes responses slower, and models can still miss details buried in the middle of very long inputs. Send what the model needs, not everything you have.<\/div>\n\n<h2 id=\"input-output\">Input tokens, output tokens and max output<\/h2>\n<p>Providers count two kinds of tokens separately:<\/p>\n<div class=\"dd-cards\">\n<div class=\"dd-card\"><b>Input tokens<\/b>Everything you send: system prompt, history, documents, tool definitions and your message. Usually the cheaper price per token.<\/div>\n<div class=\"dd-card\"><b>Output tokens<\/b>Everything the model writes back. Usually several times more expensive than input. For &#8220;reasoning&#8221; models, hidden thinking tokens are also billed as output.<\/div>\n<div class=\"dd-card\"><b>Max output tokens<\/b>A limit you set per request (<code>max_output_tokens<\/code> in OpenAI&#8217;s Responses API, <code>max_tokens<\/code> in Anthropic&#8217;s Messages API). The model stops when it hits it, even mid-sentence.<\/div>\n<\/div>\n<p>Each model also has its own <strong>maximum output<\/strong> (for example tens of thousands of tokens), which is usually far smaller than its context window. So a model with a 1M-token window can read a whole book, but it cannot write a whole book back in one reply.<\/p>\n\n<h2 id=\"budget\">Will it fit? A token budget calculator<\/h2>\n<p>Before sending a big request, a good habit is to check two things: does <em>input + max output<\/em> fit in the context window, and roughly what will it cost? This small script does both. The prices are <strong>example numbers only<\/strong> (per 1 million tokens); real prices change often, so always check your provider&#8217;s pricing page.<\/p>\n<div class=\"dd-vsc\" role=\"group\" aria-label=\"Code editor: token_budget.py\">\n<input type=\"radio\" name=\"v2\" id=\"v2f1\" class=\"f1\" checked>\n<input type=\"checkbox\" id=\"v2r1\" class=\"r1\">\n<div class=\"dd-vsc-bar\"><span class=\"dd-dots\"><i><\/i><i><\/i><i><\/i><\/span><span class=\"dd-vsc-title\">token_budget.py \u2014 devdojo-genai \u2014 Visual Studio Code<\/span><\/div>\n<div class=\"dd-vsc-tabs\">\n<label for=\"v2f1\" class=\"t1\"><b class=\"ic py\">PY<\/b>token_budget.py<\/label>\n<label for=\"v2r1\" class=\"run run1\" title=\"Show the output in the terminal\">\u25b6 Run<\/label>\n<\/div>\n<div class=\"dd-vsc-pane p1\">\n<div class=\"dd-vsc-crumbs\">devdojo-genai \u203a token_budget.py<\/div>\n<pre class=\"dd-vsc-code\"><code><span class=\"l\"><span class=\"c\"># A tiny \"will it fit, and what will it cost?\" calculator.<\/span><\/span>\n<span class=\"l\"><span class=\"c\"># Prices below are EXAMPLE numbers - always check your provider's pricing page.<\/span><\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"k\">def<\/span> <span class=\"nf\">check_request<\/span>(<span class=\"n\">input_tokens<\/span>, <span class=\"n\">max_output_tokens<\/span>, <span class=\"n\">context_window<\/span>,<\/span>\n<span class=\"l\">                  <span class=\"n\">price_in_per_m<\/span>, <span class=\"n\">price_out_per_m<\/span>):<\/span>\n<span class=\"l\">    <span class=\"n\">total<\/span> = <span class=\"n\">input_tokens<\/span> + <span class=\"n\">max_output_tokens<\/span><\/span>\n<span class=\"l\">    <span class=\"n\">fits<\/span> = <span class=\"n\">total<\/span> &lt;= <span class=\"n\">context_window<\/span><\/span>\n<span class=\"l\">    <span class=\"c\"># worst case: assumes the model uses the full max output<\/span><\/span>\n<span class=\"l\">    <span class=\"n\">cost<\/span> = (<span class=\"n\">input_tokens<\/span> * <span class=\"n\">price_in_per_m<\/span> + <span class=\"n\">max_output_tokens<\/span> * <span class=\"n\">price_out_per_m<\/span>) \/ <span class=\"m\">1_000_000<\/span><\/span>\n<span class=\"l\">    <span class=\"k\">return<\/span> <span class=\"n\">fits<\/span>, <span class=\"n\">total<\/span>, <span class=\"n\">cost<\/span><\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"n\">requests<\/span> = [<\/span>\n<span class=\"l\">    <span class=\"c\"># name,               input,   max output, context window<\/span><\/span>\n<span class=\"l\">    (<span class=\"s\">\"short chat reply\"<\/span>,   <span class=\"m\">1_200<\/span>,      <span class=\"m\">500<\/span>,    <span class=\"m\">128_000<\/span>),<\/span>\n<span class=\"l\">    (<span class=\"s\">\"summarise a PDF\"<\/span>,   <span class=\"m\">95_000<\/span>,    <span class=\"m\">2_000<\/span>,    <span class=\"m\">128_000<\/span>),<\/span>\n<span class=\"l\">    (<span class=\"s\">\"whole codebase\"<\/span>,   <span class=\"m\">180_000<\/span>,    <span class=\"m\">4_000<\/span>,    <span class=\"m\">128_000<\/span>),<\/span>\n<span class=\"l\">    (<span class=\"s\">\"whole codebase\"<\/span>,   <span class=\"m\">180_000<\/span>,    <span class=\"m\">4_000<\/span>,  <span class=\"m\">1_000_000<\/span>),<\/span>\n<span class=\"l\">]<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"k\">for<\/span> <span class=\"n\">name<\/span>, <span class=\"n\">inp<\/span>, <span class=\"n\">out<\/span>, <span class=\"n\">window<\/span> <span class=\"k\">in<\/span> <span class=\"n\">requests<\/span>:<\/span>\n<span class=\"l\">    <span class=\"n\">fits<\/span>, <span class=\"n\">total<\/span>, <span class=\"n\">cost<\/span> = <span class=\"n\">check_request<\/span>(<span class=\"n\">inp<\/span>, <span class=\"n\">out<\/span>, <span class=\"n\">window<\/span>,<\/span>\n<span class=\"l\">                                      <span class=\"n\">price_in_per_m<\/span>=<span class=\"m\">2.00<\/span>, <span class=\"n\">price_out_per_m<\/span>=<span class=\"m\">8.00<\/span>)<\/span>\n<span class=\"l\">    <span class=\"n\">status<\/span> = <span class=\"s\">\"fits\"<\/span> <span class=\"k\">if<\/span> <span class=\"n\">fits<\/span> <span class=\"k\">else<\/span> <span class=\"s\">\"TOO BIG\"<\/span><\/span>\n<span class=\"l\">    <span class=\"nb\">print<\/span>(<span class=\"s\">f\"{<\/span><span class=\"n\">name<\/span><span class=\"s\">:&lt;17} {<\/span><span class=\"n\">total<\/span><span class=\"s\">:&gt;8,} \/ {<\/span><span class=\"n\">window<\/span><span class=\"s\">:&gt;9,} tokens  {<\/span><span class=\"n\">status<\/span><span class=\"s\">:&lt;7}  ~${<\/span><span class=\"n\">cost<\/span><span class=\"s\">:.4f}\"<\/span>)<\/span><\/code><\/pre>\n<div class=\"dd-vsc-term\"><div class=\"dd-term-head\"><span>TERMINAL<\/span><span>OUTPUT<\/span><span>PROBLEMS<\/span><span class=\"dd-term-note\">Real output \u2013 Python 3 (example prices)<\/span><\/div><pre><code><span class=\"gp\">$<\/span> python token_budget.py\nshort chat reply     1,700 \/   128,000 tokens  fits     ~$0.0064\nsummarise a PDF     97,000 \/   128,000 tokens  fits     ~$0.2060\nwhole codebase     184,000 \/   128,000 tokens  TOO BIG  ~$0.3920\nwhole codebase     184,000 \/ 1,000,000 tokens  fits     ~$0.3920<\/code><\/pre><\/div>\n<div class=\"dd-vsc-status\"><span>\u2387 main<\/span><span>Ln 24, Col 1<\/span><span class=\"sp\"><\/span><span>Spaces: 4<\/span><span>UTF-8<\/span><span>LF<\/span><span>Python<\/span><\/div>\n<\/div>\n<\/div>\n<p class=\"dd-vsc-hint\">Press <strong>\u25b6 Run<\/strong> to see which requests fit.<\/p>\n<p>The &#8220;whole codebase&#8221; request fails on a 128K-token model but fits easily in a 1M-token model. Notice the cost does not change with the window size: you pay for the tokens you actually send and receive, not for the empty space.<\/p>\n<\/div>\n\n\n\n<div class=\"dd-post\">\n<h2 id=\"long-chats\">Why chatbots forget: managing long conversations<\/h2>\n<p>LLM APIs are <strong>stateless<\/strong>. The model does not remember your last request. A chat app &#8220;remembers&#8221; by sending the whole conversation again on every turn. As the chat grows, the history eats more and more of the context window until something has to give. Apps usually choose one of these strategies:<\/p>\n<ol>\n<li><strong>Sliding window:<\/strong> drop the oldest messages (simple and very common).<\/li>\n<li><strong>Summarise:<\/strong> replace old messages with a short summary written by the model.<\/li>\n<li><strong>Retrieve:<\/strong> store old messages or documents in a database and pull back only the relevant ones (this is RAG, coming in Part 11).<\/li>\n<\/ol>\n<p>That is why a long chat can &#8220;forget&#8221; what you said at the start. Here is the sliding-window strategy in code. It always keeps the system message, then adds messages from newest to oldest until the budget is used up.<\/p>\n<div class=\"dd-vsc\" role=\"group\" aria-label=\"Code editor: trim_history.py, trim-history.mjs\">\n<input type=\"radio\" name=\"v3\" id=\"v3f1\" class=\"f1\" checked>\n<input type=\"radio\" name=\"v3\" id=\"v3f2\" class=\"f2\">\n<input type=\"checkbox\" id=\"v3r1\" class=\"r1\">\n<input type=\"checkbox\" id=\"v3r2\" class=\"r2\">\n<div class=\"dd-vsc-bar\"><span class=\"dd-dots\"><i><\/i><i><\/i><i><\/i><\/span><span class=\"dd-vsc-title\">2 files \u2014 devdojo-genai \u2014 Visual Studio Code<\/span><\/div>\n<div class=\"dd-vsc-tabs\">\n<label for=\"v3f1\" class=\"t1\"><b class=\"ic py\">PY<\/b>trim_history.py<\/label>\n<label for=\"v3f2\" class=\"t2\"><b class=\"ic js\">JS<\/b>trim-history.mjs<\/label>\n<label for=\"v3r1\" class=\"run run1\" title=\"Show the output in the terminal\">\u25b6 Run<\/label>\n<label for=\"v3r2\" class=\"run run2\" title=\"Show the output in the terminal\">\u25b6 Run<\/label>\n<\/div>\n<div class=\"dd-vsc-pane p1\">\n<div class=\"dd-vsc-crumbs\">devdojo-genai \u203a trim_history.py<\/div>\n<pre class=\"dd-vsc-code\"><code><span class=\"l\"><span class=\"c\"># Keep a chat inside a token budget by dropping the OLDEST messages first.<\/span><\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"k\">def<\/span> <span class=\"nf\">estimate_tokens<\/span>(<span class=\"n\">text<\/span>):<\/span>\n<span class=\"l\">    <span class=\"c\"># Rough rule for English: 1 token is about 4 characters.<\/span><\/span>\n<span class=\"l\">    <span class=\"c\"># Use a real tokenizer (tiktoken \/ count_tokens API) when you need exact numbers.<\/span><\/span>\n<span class=\"l\">    <span class=\"k\">return<\/span> <span class=\"nb\">max<\/span>(<span class=\"m\">1<\/span>, <span class=\"nb\">len<\/span>(<span class=\"n\">text<\/span>) \/\/ <span class=\"m\">4<\/span>)<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"k\">def<\/span> <span class=\"nf\">trim_history<\/span>(<span class=\"n\">messages<\/span>, <span class=\"n\">budget<\/span>):<\/span>\n<span class=\"l\">    <span class=\"n\">system<\/span>, <span class=\"n\">chat<\/span> = <span class=\"n\">messages<\/span>[<span class=\"m\">0<\/span>], <span class=\"n\">messages<\/span>[<span class=\"m\">1<\/span>:]   <span class=\"c\"># always keep the system message<\/span><\/span>\n<span class=\"l\">    <span class=\"n\">used<\/span> = <span class=\"n\">estimate_tokens<\/span>(<span class=\"n\">system<\/span>[<span class=\"s\">\"content\"<\/span>])<\/span>\n<span class=\"l\">    <span class=\"n\">kept<\/span> = []<\/span>\n<span class=\"l\">    <span class=\"k\">for<\/span> <span class=\"n\">msg<\/span> <span class=\"k\">in<\/span> <span class=\"nb\">reversed<\/span>(<span class=\"n\">chat<\/span>):                  <span class=\"c\"># walk from newest to oldest<\/span><\/span>\n<span class=\"l\">        <span class=\"n\">cost<\/span> = <span class=\"n\">estimate_tokens<\/span>(<span class=\"n\">msg<\/span>[<span class=\"s\">\"content\"<\/span>])<\/span>\n<span class=\"l\">        <span class=\"k\">if<\/span> <span class=\"n\">used<\/span> + <span class=\"n\">cost<\/span> &gt; <span class=\"n\">budget<\/span>:<\/span>\n<span class=\"l\">            <span class=\"k\">break<\/span><\/span>\n<span class=\"l\">        <span class=\"n\">kept<\/span>.<span class=\"n\">append<\/span>(<span class=\"n\">msg<\/span>)<\/span>\n<span class=\"l\">        <span class=\"n\">used<\/span> += <span class=\"n\">cost<\/span><\/span>\n<span class=\"l\">    <span class=\"k\">return<\/span> [<span class=\"n\">system<\/span>] + <span class=\"nb\">list<\/span>(<span class=\"nb\">reversed<\/span>(<span class=\"n\">kept<\/span>)), <span class=\"n\">used<\/span><\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"n\">messages<\/span> = [<\/span>\n<span class=\"l\">    {<span class=\"s\">\"role\"<\/span>: <span class=\"s\">\"system\"<\/span>, <span class=\"s\">\"content\"<\/span>: <span class=\"s\">\"You are a helpful coding tutor.\"<\/span>},<\/span>\n<span class=\"l\">    {<span class=\"s\">\"role\"<\/span>: <span class=\"s\">\"user\"<\/span>, <span class=\"s\">\"content\"<\/span>: <span class=\"s\">\"What is a token? \"<\/span> * <span class=\"m\">20<\/span>},<\/span>\n<span class=\"l\">    {<span class=\"s\">\"role\"<\/span>: <span class=\"s\">\"assistant\"<\/span>, <span class=\"s\">\"content\"<\/span>: <span class=\"s\">\"A token is a small piece of text. \"<\/span> * <span class=\"m\">20<\/span>},<\/span>\n<span class=\"l\">    {<span class=\"s\">\"role\"<\/span>: <span class=\"s\">\"user\"<\/span>, <span class=\"s\">\"content\"<\/span>: <span class=\"s\">\"And what is a context window? \"<\/span> * <span class=\"m\">10<\/span>},<\/span>\n<span class=\"l\">    {<span class=\"s\">\"role\"<\/span>: <span class=\"s\">\"assistant\"<\/span>, <span class=\"s\">\"content\"<\/span>: <span class=\"s\">\"It is the model's working memory. \"<\/span> * <span class=\"m\">10<\/span>},<\/span>\n<span class=\"l\">    {<span class=\"s\">\"role\"<\/span>: <span class=\"s\">\"user\"<\/span>, <span class=\"s\">\"content\"<\/span>: <span class=\"s\">\"Give me one example.\"<\/span>},<\/span>\n<span class=\"l\">]<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"n\">trimmed<\/span>, <span class=\"n\">used<\/span> = <span class=\"n\">trim_history<\/span>(<span class=\"n\">messages<\/span>, <span class=\"n\">budget<\/span>=<span class=\"m\">250<\/span>)<\/span>\n<span class=\"l\"><span class=\"nb\">print<\/span>(<span class=\"s\">f\"kept {<\/span><span class=\"nb\">len<\/span>(<span class=\"n\">trimmed<\/span>)<span class=\"s\">} of {<\/span><span class=\"nb\">len<\/span>(<span class=\"n\">messages<\/span>)<span class=\"s\">} messages, ~{<\/span><span class=\"n\">used<\/span><span class=\"s\">} tokens\"<\/span>)<\/span>\n<span class=\"l\"><span class=\"k\">for<\/span> <span class=\"n\">m<\/span> <span class=\"k\">in<\/span> <span class=\"n\">trimmed<\/span>:<\/span>\n<span class=\"l\">    <span class=\"nb\">print<\/span>(<span class=\"s\">f\"- {<\/span><span class=\"n\">m<\/span>[<span class=\"s\">'role'<\/span>]<span class=\"s\">:&lt;9} {<\/span><span class=\"n\">m<\/span>[<span class=\"s\">'content'<\/span>][:<span class=\"m\">40<\/span>]<span class=\"s\">!r}\"<\/span>)<\/span><\/code><\/pre>\n<div class=\"dd-vsc-term\"><div class=\"dd-term-head\"><span>TERMINAL<\/span><span>OUTPUT<\/span><span>PROBLEMS<\/span><span class=\"dd-term-note\">Real output \u2013 Python 3<\/span><\/div><pre><code><span class=\"gp\">$<\/span> python trim_history.py\nkept 4 of 6 messages, ~172 tokens\n- system    'You are a helpful coding tutor.'\n- user      'And what is a context window? And what i'\n- assistant \"It is the model's working memory. It is \"\n- user      'Give me one example.'<\/code><\/pre><\/div>\n<div class=\"dd-vsc-status\"><span>\u2387 main<\/span><span>Ln 32, Col 1<\/span><span class=\"sp\"><\/span><span>Spaces: 4<\/span><span>UTF-8<\/span><span>LF<\/span><span>Python<\/span><\/div>\n<\/div>\n<div class=\"dd-vsc-pane p2\">\n<div class=\"dd-vsc-crumbs\">devdojo-genai \u203a trim-history.mjs<\/div>\n<pre class=\"dd-vsc-code\"><code><span class=\"l\"><span class=\"c\">\/\/ Keep a chat inside a token budget by dropping the OLDEST messages first.<\/span><\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"k\">function<\/span> <span class=\"n\">estimateTokens<\/span>(<span class=\"n\">text<\/span>) {<\/span>\n<span class=\"l\">  <span class=\"c\">\/\/ Rough rule for English: 1 token is about 4 characters.<\/span><\/span>\n<span class=\"l\">  <span class=\"k\">return<\/span> <span class=\"nb\">Math<\/span>.<span class=\"n\">max<\/span>(<span class=\"m\">1<\/span>, <span class=\"nb\">Math<\/span>.<span class=\"n\">floor<\/span>(<span class=\"n\">text<\/span>.<span class=\"n\">length<\/span> \/ <span class=\"m\">4<\/span>));<\/span>\n<span class=\"l\">}<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"k\">function<\/span> <span class=\"n\">trimHistory<\/span>(<span class=\"n\">messages<\/span>, <span class=\"n\">budget<\/span>) {<\/span>\n<span class=\"l\">  <span class=\"k\">const<\/span> [<span class=\"n\">system<\/span>, ...<span class=\"n\">chat<\/span>] = <span class=\"n\">messages<\/span>; <span class=\"c\">\/\/ always keep the system message<\/span><\/span>\n<span class=\"l\">  <span class=\"k\">let<\/span> <span class=\"n\">used<\/span> = <span class=\"n\">estimateTokens<\/span>(<span class=\"n\">system<\/span>.<span class=\"n\">content<\/span>);<\/span>\n<span class=\"l\">  <span class=\"k\">const<\/span> <span class=\"n\">kept<\/span> = [];<\/span>\n<span class=\"l\">  <span class=\"k\">for<\/span> (<span class=\"k\">const<\/span> <span class=\"n\">msg<\/span> <span class=\"k\">of<\/span> [...<span class=\"n\">chat<\/span>].<span class=\"n\">reverse<\/span>()) { <span class=\"c\">\/\/ newest to oldest<\/span><\/span>\n<span class=\"l\">    <span class=\"k\">const<\/span> <span class=\"n\">cost<\/span> = <span class=\"n\">estimateTokens<\/span>(<span class=\"n\">msg<\/span>.<span class=\"n\">content<\/span>);<\/span>\n<span class=\"l\">    <span class=\"k\">if<\/span> (<span class=\"n\">used<\/span> + <span class=\"n\">cost<\/span> &gt; <span class=\"n\">budget<\/span>) <span class=\"k\">break<\/span>;<\/span>\n<span class=\"l\">    <span class=\"n\">kept<\/span>.<span class=\"n\">unshift<\/span>(<span class=\"n\">msg<\/span>);<\/span>\n<span class=\"l\">    <span class=\"n\">used<\/span> += <span class=\"n\">cost<\/span>;<\/span>\n<span class=\"l\">  }<\/span>\n<span class=\"l\">  <span class=\"k\">return<\/span> { <span class=\"n\">trimmed<\/span>: [<span class=\"n\">system<\/span>, ...<span class=\"n\">kept<\/span>], <span class=\"n\">used<\/span> };<\/span>\n<span class=\"l\">}<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"k\">const<\/span> <span class=\"n\">messages<\/span> = [<\/span>\n<span class=\"l\">  { <span class=\"n\">role<\/span>: <span class=\"s\">\"system\"<\/span>, <span class=\"n\">content<\/span>: <span class=\"s\">\"You are a helpful coding tutor.\"<\/span> },<\/span>\n<span class=\"l\">  { <span class=\"n\">role<\/span>: <span class=\"s\">\"user\"<\/span>, <span class=\"n\">content<\/span>: <span class=\"s\">\"What is a token? \"<\/span>.<span class=\"n\">repeat<\/span>(<span class=\"m\">20<\/span>) },<\/span>\n<span class=\"l\">  { <span class=\"n\">role<\/span>: <span class=\"s\">\"assistant\"<\/span>, <span class=\"n\">content<\/span>: <span class=\"s\">\"A token is a small piece of text. \"<\/span>.<span class=\"n\">repeat<\/span>(<span class=\"m\">20<\/span>) },<\/span>\n<span class=\"l\">  { <span class=\"n\">role<\/span>: <span class=\"s\">\"user\"<\/span>, <span class=\"n\">content<\/span>: <span class=\"s\">\"And what is a context window? \"<\/span>.<span class=\"n\">repeat<\/span>(<span class=\"m\">10<\/span>) },<\/span>\n<span class=\"l\">  { <span class=\"n\">role<\/span>: <span class=\"s\">\"assistant\"<\/span>, <span class=\"n\">content<\/span>: <span class=\"s\">\"It is the model's working memory. \"<\/span>.<span class=\"n\">repeat<\/span>(<span class=\"m\">10<\/span>) },<\/span>\n<span class=\"l\">  { <span class=\"n\">role<\/span>: <span class=\"s\">\"user\"<\/span>, <span class=\"n\">content<\/span>: <span class=\"s\">\"Give me one example.\"<\/span> },<\/span>\n<span class=\"l\">];<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"k\">const<\/span> { <span class=\"n\">trimmed<\/span>, <span class=\"n\">used<\/span> } = <span class=\"n\">trimHistory<\/span>(<span class=\"n\">messages<\/span>, <span class=\"m\">250<\/span>);<\/span>\n<span class=\"l\"><span class=\"n\">console<\/span>.<span class=\"n\">log<\/span>(<span class=\"s\">`kept ${<\/span><span class=\"n\">trimmed<\/span>.<span class=\"n\">length<\/span><span class=\"s\">} of ${<\/span><span class=\"n\">messages<\/span>.<span class=\"n\">length<\/span><span class=\"s\">} messages, ~${<\/span><span class=\"n\">used<\/span><span class=\"s\">} tokens`<\/span>);<\/span>\n<span class=\"l\"><span class=\"k\">for<\/span> (<span class=\"k\">const<\/span> <span class=\"n\">m<\/span> <span class=\"k\">of<\/span> <span class=\"n\">trimmed<\/span>) <span class=\"n\">console<\/span>.<span class=\"n\">log<\/span>(<span class=\"s\">`- ${<\/span><span class=\"n\">m<\/span>.<span class=\"n\">role<\/span>.<span class=\"n\">padEnd<\/span>(<span class=\"m\">9<\/span>)<span class=\"s\">} ${<\/span><span class=\"nb\">JSON<\/span>.<span class=\"n\">stringify<\/span>(<span class=\"n\">m<\/span>.<span class=\"n\">content<\/span>.<span class=\"n\">slice<\/span>(<span class=\"m\">0<\/span>, <span class=\"m\">40<\/span>))<span class=\"s\">}`<\/span>);<\/span><\/code><\/pre>\n<div class=\"dd-vsc-term\"><div class=\"dd-term-head\"><span>TERMINAL<\/span><span>OUTPUT<\/span><span>PROBLEMS<\/span><span class=\"dd-term-note\">Real output \u2013 Node.js 22<\/span><\/div><pre><code><span class=\"gp\">$<\/span> node trim-history.mjs\nkept 4 of 6 messages, ~172 tokens\n- system    \"You are a helpful coding tutor.\"\n- user      \"And what is a context window? And what i\"\n- assistant \"It is the model's working memory. It is \"\n- user      \"Give me one example.\"<\/code><\/pre><\/div>\n<div class=\"dd-vsc-status\"><span>\u2387 main<\/span><span>Ln 32, Col 1<\/span><span class=\"sp\"><\/span><span>Spaces: 2<\/span><span>UTF-8<\/span><span>LF<\/span><span>JavaScript<\/span><\/div>\n<\/div>\n<\/div>\n<p class=\"dd-vsc-hint\">Same logic in two languages. Switch tabs and press <strong>\u25b6 Run<\/strong>.<\/p>\n<p>The two oldest messages were dropped, and the newest question survived. In production, replace the rough <code>len(text) \/\/ 4<\/code> estimate with a real tokenizer for the model you use.<\/p>\n<div class=\"dd-note\"><strong>Research note:<\/strong> the paper <a href=\"https:\/\/arxiv.org\/abs\/2307.03172\" target=\"_blank\" rel=\"noopener\">&#8220;Lost in the Middle: How Language Models Use Long Contexts&#8221;<\/a> found that models used information at the start and end of a long input better than information in the middle. Newer models handle long inputs much better, but the practical advice still holds: put the most important instructions and facts near the start or end.<\/div>\n\n<h2 id=\"usage\">Read real token usage from an API<\/h2>\n<p>Local tokenizers are great for estimates, but the most accurate number comes from the provider itself. Every response includes a <strong>usage<\/strong> object, and some providers also let you count tokens <em>before<\/em> you send. Below, the first file reads usage from OpenAI&#8217;s Responses API. The second uses Anthropic&#8217;s free <a href=\"https:\/\/platform.claude.com\/docs\/en\/build-with-claude\/token-counting\" target=\"_blank\" rel=\"noopener\">token counting endpoint<\/a> to check the size first, then sends the real request.<\/p>\n<div class=\"dd-vsc\" role=\"group\" aria-label=\"Code editor: usage_openai.py, count_claude.py\">\n<input type=\"radio\" name=\"v4\" id=\"v4f1\" class=\"f1\" checked>\n<input type=\"radio\" name=\"v4\" id=\"v4f2\" class=\"f2\">\n<input type=\"checkbox\" id=\"v4r1\" class=\"r1\">\n<input type=\"checkbox\" id=\"v4r2\" class=\"r2\">\n<div class=\"dd-vsc-bar\"><span class=\"dd-dots\"><i><\/i><i><\/i><i><\/i><\/span><span class=\"dd-vsc-title\">2 files \u2014 devdojo-genai \u2014 Visual Studio Code<\/span><\/div>\n<div class=\"dd-vsc-tabs\">\n<label for=\"v4f1\" class=\"t1\"><b class=\"ic py\">PY<\/b>usage_openai.py<\/label>\n<label for=\"v4f2\" class=\"t2\"><b class=\"ic py\">PY<\/b>count_claude.py<\/label>\n<label for=\"v4r1\" class=\"run run1\" title=\"Show the output in the terminal\">\u25b6 Run<\/label>\n<label for=\"v4r2\" class=\"run run2\" title=\"Show the output in the terminal\">\u25b6 Run<\/label>\n<\/div>\n<div class=\"dd-vsc-pane p1\">\n<div class=\"dd-vsc-crumbs\">devdojo-genai \u203a usage_openai.py<\/div>\n<pre class=\"dd-vsc-code\"><code><span class=\"l\"><span class=\"c\"># pip install openai      (needs OPENAI_API_KEY)<\/span><\/span>\n<span class=\"l\"><span class=\"kn\">import<\/span> <span class=\"n\">os<\/span><\/span>\n<span class=\"l\"><span class=\"kn\">from<\/span> <span class=\"n\">openai<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">OpenAI<\/span><\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"n\">client<\/span> = <span class=\"n\">OpenAI<\/span>()<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"n\">response<\/span> = <span class=\"n\">client<\/span>.<span class=\"n\">responses<\/span>.<span class=\"n\">create<\/span>(<\/span>\n<span class=\"l\">    <span class=\"n\">model<\/span>=<span class=\"n\">os<\/span>.<span class=\"n\">getenv<\/span>(<span class=\"s\">\"OPENAI_MODEL\"<\/span>, <span class=\"s\">\"gpt-5.5\"<\/span>),   <span class=\"c\"># check the models page for the latest<\/span><\/span>\n<span class=\"l\">    <span class=\"nb\">input<\/span>=<span class=\"s\">\"Explain a context window in one sentence.\"<\/span>,<\/span>\n<span class=\"l\">    <span class=\"n\">max_output_tokens<\/span>=<span class=\"m\">300<\/span>,                         <span class=\"c\"># upper limit for the answer<\/span><\/span>\n<span class=\"l\">)<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"nb\">print<\/span>(<span class=\"n\">response<\/span>.<span class=\"n\">output_text<\/span>)<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"n\">usage<\/span> = <span class=\"n\">response<\/span>.<span class=\"n\">usage<\/span><\/span>\n<span class=\"l\"><span class=\"nb\">print<\/span>(<span class=\"s\">\"input tokens :\"<\/span>, <span class=\"n\">usage<\/span>.<span class=\"n\">input_tokens<\/span>)<\/span>\n<span class=\"l\"><span class=\"nb\">print<\/span>(<span class=\"s\">\"output tokens:\"<\/span>, <span class=\"n\">usage<\/span>.<span class=\"n\">output_tokens<\/span>)       <span class=\"c\"># includes any hidden reasoning tokens<\/span><\/span>\n<span class=\"l\"><span class=\"nb\">print<\/span>(<span class=\"s\">\"total tokens :\"<\/span>, <span class=\"n\">usage<\/span>.<span class=\"n\">total_tokens<\/span>)<\/span><\/code><\/pre>\n<div class=\"dd-vsc-term\"><div class=\"dd-term-head\"><span>TERMINAL<\/span><span>OUTPUT<\/span><span>PROBLEMS<\/span><span class=\"dd-term-note\">Example output \u2013 your numbers will differ<\/span><\/div><pre><code><span class=\"gp\">$<\/span> python usage_openai.py\n&lt;one-sentence answer from the model&gt;\ninput tokens : &lt;number&gt;\noutput tokens: &lt;number&gt;\ntotal tokens : &lt;number&gt;<\/code><\/pre><\/div>\n<div class=\"dd-vsc-status\"><span>\u2387 main<\/span><span>Ln 18, Col 1<\/span><span class=\"sp\"><\/span><span>Spaces: 4<\/span><span>UTF-8<\/span><span>LF<\/span><span>Python<\/span><\/div>\n<\/div>\n<div class=\"dd-vsc-pane p2\">\n<div class=\"dd-vsc-crumbs\">devdojo-genai \u203a count_claude.py<\/div>\n<pre class=\"dd-vsc-code\"><code><span class=\"l\"><span class=\"c\"># pip install anthropic   (needs ANTHROPIC_API_KEY)<\/span><\/span>\n<span class=\"l\"><span class=\"kn\">import<\/span> <span class=\"n\">os<\/span><\/span>\n<span class=\"l\"><span class=\"kn\">import<\/span> <span class=\"n\">anthropic<\/span><\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"n\">client<\/span> = <span class=\"n\">anthropic<\/span>.<span class=\"n\">Anthropic<\/span>()<\/span>\n<span class=\"l\"><span class=\"n\">model<\/span> = <span class=\"n\">os<\/span>.<span class=\"n\">getenv<\/span>(<span class=\"s\">\"ANTHROPIC_MODEL\"<\/span>, <span class=\"s\">\"claude-sonnet-5-5\"<\/span>)<\/span>\n<span class=\"l\"><span class=\"n\">messages<\/span> = [{<span class=\"s\">\"role\"<\/span>: <span class=\"s\">\"user\"<\/span>, <span class=\"s\">\"content\"<\/span>: <span class=\"s\">\"Explain a context window in one sentence.\"<\/span>}]<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"c\"># 1) Count BEFORE sending (free, rate-limited estimate)<\/span><\/span>\n<span class=\"l\"><span class=\"n\">count<\/span> = <span class=\"n\">client<\/span>.<span class=\"n\">messages<\/span>.<span class=\"n\">count_tokens<\/span>(<\/span>\n<span class=\"l\">    <span class=\"n\">model<\/span>=<span class=\"n\">model<\/span>,<\/span>\n<span class=\"l\">    <span class=\"n\">system<\/span>=<span class=\"s\">\"You are a friendly teacher.\"<\/span>,<\/span>\n<span class=\"l\">    <span class=\"n\">messages<\/span>=<span class=\"n\">messages<\/span>,<\/span>\n<span class=\"l\">)<\/span>\n<span class=\"l\"><span class=\"nb\">print<\/span>(<span class=\"s\">\"will send about\"<\/span>, <span class=\"n\">count<\/span>.<span class=\"n\">input_tokens<\/span>, <span class=\"s\">\"input tokens\"<\/span>)<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"c\"># 2) Send the real request and read the usage that comes back<\/span><\/span>\n<span class=\"l\"><span class=\"n\">reply<\/span> = <span class=\"n\">client<\/span>.<span class=\"n\">messages<\/span>.<span class=\"n\">create<\/span>(<\/span>\n<span class=\"l\">    <span class=\"n\">model<\/span>=<span class=\"n\">model<\/span>,<\/span>\n<span class=\"l\">    <span class=\"n\">max_tokens<\/span>=<span class=\"m\">300<\/span>,<\/span>\n<span class=\"l\">    <span class=\"n\">system<\/span>=<span class=\"s\">\"You are a friendly teacher.\"<\/span>,<\/span>\n<span class=\"l\">    <span class=\"n\">messages<\/span>=<span class=\"n\">messages<\/span>,<\/span>\n<span class=\"l\">)<\/span>\n<span class=\"l\"><span class=\"nb\">print<\/span>(<span class=\"n\">reply<\/span>.<span class=\"n\">content<\/span>[<span class=\"m\">0<\/span>].<span class=\"n\">text<\/span>)<\/span>\n<span class=\"l\"><span class=\"nb\">print<\/span>(<span class=\"s\">\"input:\"<\/span>, <span class=\"n\">reply<\/span>.<span class=\"n\">usage<\/span>.<span class=\"n\">input_tokens<\/span>, <span class=\"s\">\"output:\"<\/span>, <span class=\"n\">reply<\/span>.<span class=\"n\">usage<\/span>.<span class=\"n\">output_tokens<\/span>)<\/span><\/code><\/pre>\n<div class=\"dd-vsc-term\"><div class=\"dd-term-head\"><span>TERMINAL<\/span><span>OUTPUT<\/span><span>PROBLEMS<\/span><span class=\"dd-term-note\">Example output \u2013 your numbers will differ<\/span><\/div><pre><code><span class=\"gp\">$<\/span> python count_claude.py\nwill send about &lt;number&gt; input tokens\n&lt;one-sentence answer from the model&gt;\ninput: &lt;number&gt; output: &lt;number&gt;<\/code><\/pre><\/div>\n<div class=\"dd-vsc-status\"><span>\u2387 main<\/span><span>Ln 25, Col 1<\/span><span class=\"sp\"><\/span><span>Spaces: 4<\/span><span>UTF-8<\/span><span>LF<\/span><span>Python<\/span><\/div>\n<\/div>\n<\/div>\n<p class=\"dd-vsc-hint\">Two providers, two files. Click the tabs, then <strong>\u25b6 Run<\/strong> to see the shape of the output. You need your own API keys to run them.<\/p>\n<p>We set the model name through an environment variable (<code>OPENAI_MODEL<\/code> \/ <code>ANTHROPIC_MODEL<\/code>) so you can switch models without editing code. Model names change often, so check each provider&#8217;s models page. We will set up API keys and call OpenAI, Anthropic and Gemini step by step in Part 3.<\/p>\n<div class=\"dd-tip\"><strong>Tip:<\/strong> log the usage numbers of every request in your app. It is the easiest way to spot a prompt that suddenly got huge (and expensive).<\/div>\n<\/div>\n\n\n\n<div class=\"dd-post\">\n<h2 id=\"parameters\">What are model parameters? What does &#8220;8B&#8221; mean?<\/h2>\n<p>A neural network is a huge pile of numbers called <strong>weights<\/strong> (together with a few other learned values, they are the model&#8217;s <strong>parameters<\/strong>). During training, each wrong next-token guess nudges these numbers a tiny bit. After trillions of nudges, the numbers store patterns of language, facts and coding styles.<\/p>\n<p>When you see a model name like &#8220;Llama 3.1 8B&#8221;, the <strong>8B<\/strong> means about <strong>8 billion parameters<\/strong>. A useful mental picture: parameters are the model&#8217;s <em>long-term knowledge<\/em> (fixed after training), while the context window is its <em>short-term working memory<\/em> (fresh for every request).<\/p>\n<p>Click through the sizes below to see what each class of model is good for:<\/p>\n<div class=\"dd-tabs\" role=\"group\" aria-label=\"Model size explorer\">\n<input type=\"radio\" name=\"ddsize\" id=\"ti1\" checked>\n<input type=\"radio\" name=\"ddsize\" id=\"ti2\">\n<input type=\"radio\" name=\"ddsize\" id=\"ti3\">\n<input type=\"radio\" name=\"ddsize\" id=\"ti4\">\n<div class=\"labels\"><label for=\"ti1\">Tiny (~1B)<\/label><label for=\"ti2\">Small (~8B)<\/label><label for=\"ti3\">Large (~70B)<\/label><label for=\"ti4\">Frontier (400B+)<\/label><\/div>\n<div class=\"panel p1\"><p><strong>About 1 billion parameters.<\/strong> Runs on a phone or any laptop. Fast and free, good for simple tasks like short summaries, classification or autocomplete. Makes more mistakes on reasoning and facts.<\/p><p><em>Where you see it:<\/em> on-device AI, small Ollama models such as the <code>gemma3:1b<\/code> model from Part 1.<\/p><\/div>\n<div class=\"panel p2\"><p><strong>About 7\u20138 billion parameters.<\/strong> The sweet spot for local AI. With 4-bit quantization it needs about 4\u20135 GB of memory, so it runs on a decent laptop or a gaming GPU. Good for chat, coding help and RAG over your own documents.<\/p><p><em>Where you see it:<\/em> popular open-weight models in the 7B\u20139B range.<\/p><\/div>\n<div class=\"panel p3\"><p><strong>About 70 billion parameters.<\/strong> Much stronger reasoning and knowledge. Needs about 35 GB even at 4-bit, so usually a workstation with large GPUs or a cloud server. Often used by companies that want to self-host a capable model.<\/p><p><em>Where you see it:<\/em> large open-weight models served with tools like vLLM (Part 27).<\/p><\/div>\n<div class=\"panel p4\"><p><strong>Hundreds of billions of parameters or more.<\/strong> The flagship cloud models. Providers often do not publish exact sizes, and many use a <strong>mixture-of-experts<\/strong> design where only part of the parameters is active for each token. You use these through an API, not on your own machine.<\/p><p><em>Where you see it:<\/em> ChatGPT, Claude and Gemini&#8217;s top models.<\/p><\/div>\n<\/div>\n<h3>How parameters decide memory<\/h3>\n<p>Every parameter is stored as a number. At 16-bit precision (FP16) each one takes 2 bytes. <strong>Quantization<\/strong> stores them with fewer bits (8-bit or 4-bit), which shrinks memory with only a small loss in quality. That is how 8B models run on laptops.<\/p>\n<div class=\"dd-vsc\" role=\"group\" aria-label=\"Code editor: model_memory.py\">\n<input type=\"radio\" name=\"v5\" id=\"v5f1\" class=\"f1\" checked>\n<input type=\"checkbox\" id=\"v5r1\" class=\"r1\">\n<div class=\"dd-vsc-bar\"><span class=\"dd-dots\"><i><\/i><i><\/i><i><\/i><\/span><span class=\"dd-vsc-title\">model_memory.py \u2014 devdojo-genai \u2014 Visual Studio Code<\/span><\/div>\n<div class=\"dd-vsc-tabs\">\n<label for=\"v5f1\" class=\"t1\"><b class=\"ic py\">PY<\/b>model_memory.py<\/label>\n<label for=\"v5r1\" class=\"run run1\" title=\"Show the output in the terminal\">\u25b6 Run<\/label>\n<\/div>\n<div class=\"dd-vsc-pane p1\">\n<div class=\"dd-vsc-crumbs\">devdojo-genai \u203a model_memory.py<\/div>\n<pre class=\"dd-vsc-code\"><code><span class=\"l\"><span class=\"c\"># How much memory do a model's weights need?<\/span><\/span>\n<span class=\"l\"><span class=\"c\"># memory = number of parameters x bytes per parameter<\/span><\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"n\">BYTES_PER_PARAM<\/span> = {<span class=\"s\">\"FP16\"<\/span>: <span class=\"m\">2<\/span>, <span class=\"s\">\"INT8\"<\/span>: <span class=\"m\">1<\/span>, <span class=\"s\">\"4-bit\"<\/span>: <span class=\"m\">0.5<\/span>}<\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"k\">def<\/span> <span class=\"nf\">weight_memory_gb<\/span>(<span class=\"n\">params_billion<\/span>, <span class=\"n\">precision<\/span>):<\/span>\n<span class=\"l\">    <span class=\"k\">return<\/span> <span class=\"n\">params_billion<\/span> * <span class=\"m\">1e9<\/span> * <span class=\"n\">BYTES_PER_PARAM<\/span>[<span class=\"n\">precision<\/span>] \/ <span class=\"m\">1e9<\/span><\/span>\n<span class=\"l\"><\/span>\n<span class=\"l\"><span class=\"nb\">print<\/span>(<span class=\"s\">f\"{'model size':&lt;11}\"<\/span> + <span class=\"s\">\"\"<\/span>.<span class=\"n\">join<\/span>(<span class=\"s\">f\"{<\/span><span class=\"n\">p<\/span><span class=\"s\">:&gt;10}\"<\/span> <span class=\"k\">for<\/span> <span class=\"n\">p<\/span> <span class=\"k\">in<\/span> <span class=\"n\">BYTES_PER_PARAM<\/span>))<\/span>\n<span class=\"l\"><span class=\"k\">for<\/span> <span class=\"n\">size<\/span> <span class=\"k\">in<\/span> [<span class=\"m\">1<\/span>, <span class=\"m\">8<\/span>, <span class=\"m\">70<\/span>, <span class=\"m\">405<\/span>]:<\/span>\n<span class=\"l\">    <span class=\"n\">row<\/span> = <span class=\"s\">\"\"<\/span>.<span class=\"n\">join<\/span>(<span class=\"s\">f\"{<\/span><span class=\"n\">weight_memory_gb<\/span>(<span class=\"n\">size<\/span>, <span class=\"n\">p<\/span>)<span class=\"s\">:&gt;8.1f}GB\"<\/span> <span class=\"k\">for<\/span> <span class=\"n\">p<\/span> <span class=\"k\">in<\/span> <span class=\"n\">BYTES_PER_PARAM<\/span>)<\/span>\n<span class=\"l\">    <span class=\"nb\">print<\/span>(<span class=\"s\">f\"{<\/span><span class=\"nb\">str<\/span>(<span class=\"n\">size<\/span>) + <span class=\"s\">'B':&lt;11}{<\/span><span class=\"n\">row<\/span><span class=\"s\">}\"<\/span>)<\/span>\n<span class=\"l\"><span class=\"nb\">print<\/span>(<span class=\"s\">\"(weights only - real use needs extra memory for the context \/ KV cache)\"<\/span>)<\/span><\/code><\/pre>\n<div class=\"dd-vsc-term\"><div class=\"dd-term-head\"><span>TERMINAL<\/span><span>OUTPUT<\/span><span>PROBLEMS<\/span><span class=\"dd-term-note\">Real output \u2013 Python 3<\/span><\/div><pre><code><span class=\"gp\">$<\/span> python model_memory.py\nmodel size       FP16      INT8     4-bit\n1B              2.0GB     1.0GB     0.5GB\n8B             16.0GB     8.0GB     4.0GB\n70B           140.0GB    70.0GB    35.0GB\n405B          810.0GB   405.0GB   202.5GB\n(weights only - real use needs extra memory for the context \/ KV cache)<\/code><\/pre><\/div>\n<div class=\"dd-vsc-status\"><span>\u2387 main<\/span><span>Ln 13, Col 1<\/span><span class=\"sp\"><\/span><span>Spaces: 4<\/span><span>UTF-8<\/span><span>LF<\/span><span>Python<\/span><\/div>\n<\/div>\n<\/div>\n<p class=\"dd-vsc-hint\">Press <strong>\u25b6 Run<\/strong> to see the memory table.<\/p>\n<figure>\n<svg viewBox=\"0 0 900 300\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" role=\"img\" aria-label=\"Bar chart: memory needed just for model weights at 16-bit precision, from 2 GB for a 1B model to 810 GB for a 405B model\">\n<rect width=\"900\" height=\"300\" fill=\"#f8f9fc\"\/>\n<text x=\"30\" y=\"38\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"18\" font-weight=\"700\" fill=\"#151b3b\">Memory for the weights alone (16-bit \/ FP16)<\/text>\n<text x=\"30\" y=\"62\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"14\" fill=\"#5b6275\">2 bytes per parameter. 4-bit quantized models need about a quarter of this.<\/text>\n<g font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"15\">\n<text x=\"30\" y=\"108\" fill=\"#1f2433\" font-weight=\"700\">1B<\/text><rect x=\"100\" y=\"92\" width=\"4\" height=\"24\" rx=\"3\" fill=\"#3178c6\"\/><text x=\"114\" y=\"109\" fill=\"#1f2433\">2 GB \u00b7 phone \/ laptop<\/text>\n<text x=\"30\" y=\"158\" fill=\"#1f2433\" font-weight=\"700\">8B<\/text><rect x=\"100\" y=\"142\" width=\"12\" height=\"24\" rx=\"3\" fill=\"#3178c6\"\/><text x=\"122\" y=\"159\" fill=\"#1f2433\">16 GB \u00b7 gaming GPU (4-bit: 4 GB)<\/text>\n<text x=\"30\" y=\"208\" fill=\"#1f2433\" font-weight=\"700\">70B<\/text><rect x=\"100\" y=\"192\" width=\"104\" height=\"24\" rx=\"3\" fill=\"#5a46c9\"\/><text x=\"214\" y=\"209\" fill=\"#1f2433\">140 GB \u00b7 multiple data-centre GPUs<\/text>\n<text x=\"30\" y=\"258\" fill=\"#1f2433\" font-weight=\"700\">405B<\/text><rect x=\"100\" y=\"242\" width=\"600\" height=\"24\" rx=\"3\" fill=\"#7c5cff\"\/><text x=\"712\" y=\"259\" fill=\"#1f2433\">810 GB \u00b7 GPU cluster<\/text>\n<\/g>\n<\/svg>\n<figcaption>Figure 3: Parameter count drives memory. That is why small models run locally and giant models live in the cloud.<\/figcaption>\n<\/figure>\n<p>Remember: these numbers are for the weights only. Running a model also needs memory for the context (called the <strong>KV cache<\/strong>), which grows with the number of tokens. A long context window can need several extra gigabytes, which is why local tools often default to a smaller context size.<\/p>\n<\/div>\n\n\n\n<div class=\"dd-post\">\n<h2 id=\"comparison\">Tokens vs context window vs parameters<\/h2>\n<p>These three terms are easy to mix up. Here they are side by side:<\/p>\n<div class=\"dd-tablewrap\"><table>\n<thead><tr><th>Term<\/th><th>What it is<\/th><th>Simple analogy<\/th><th>Affects<\/th><\/tr><\/thead>\n<tbody>\n<tr><td><strong>Token<\/strong><\/td><td>A small piece of text the model reads or writes<\/td><td>A word or syllable<\/td><td>Cost per request, speed<\/td><\/tr>\n<tr><td><strong>Context window<\/strong><\/td><td>Max tokens (input + output) in one request<\/td><td>Size of the desk you work on<\/td><td>How much text, history and documents you can send<\/td><\/tr>\n<tr><td><strong>Max output tokens<\/strong><\/td><td>Max tokens the model may write in one reply<\/td><td>Page limit for an answer<\/td><td>Answer length, cut-off replies<\/td><\/tr>\n<tr><td><strong>Parameters<\/strong><\/td><td>Learned numbers inside the model<\/td><td>Knowledge in your brain<\/td><td>Quality, memory needed, price per token<\/td><\/tr>\n<\/tbody><\/table><\/div>\n\n<h2 id=\"errors\">Common errors and fixes<\/h2>\n<div class=\"dd-tablewrap\"><table>\n<thead><tr><th>Problem \/ error<\/th><th>Why it happens<\/th><th>Fix<\/th><\/tr><\/thead>\n<tbody>\n<tr><td><code>context_length_exceeded<\/code> or &#8220;prompt is too long&#8221;<\/td><td>Input + max output is bigger than the model&#8217;s context window<\/td><td>Trim or summarise history, send fewer documents, lower max output, or choose a model with a bigger window<\/td><\/tr>\n<tr><td>Answer stops mid-sentence<\/td><td>The reply hit the max output limit (OpenAI: <code>status: \"incomplete\"<\/code>; Anthropic: <code>stop_reason: \"max_tokens\"<\/code>)<\/td><td>Raise the max output setting, ask for a shorter answer, or check the stop reason and continue<\/td><\/tr>\n<tr><td><code>429<\/code> rate limit on tokens<\/td><td>You sent more tokens per minute than your account allows<\/td><td>Retry with backoff, send smaller prompts, or request a higher limit<\/td><\/tr>\n<tr><td>Bill much higher than expected<\/td><td>Full chat history and documents are re-sent on every turn<\/td><td>Log <code>usage<\/code>, trim history, use prompt caching (Part 20)<\/td><\/tr>\n<tr><td>Token count differs from the provider&#8217;s number<\/td><td>You used a different tokenizer than the model&#8217;s own<\/td><td>Use the provider&#8217;s token counting API or read <code>usage<\/code> from the response<\/td><\/tr>\n<tr><td>Local model crashes with &#8220;out of memory&#8221;<\/td><td>Weights + KV cache do not fit in RAM or GPU memory<\/td><td>Pick a smaller or 4-bit quantized model, or reduce the context size<\/td><\/tr>\n<tr><td>Chatbot &#8220;forgets&#8221; early instructions<\/td><td>Old messages were dropped or buried in a very long context<\/td><td>Keep key rules in the system prompt, repeat critical facts near the end<\/td><\/tr>\n<\/tbody><\/table><\/div>\n\n<h2 id=\"best-practices\">Best practices for tokens and context<\/h2>\n<ul>\n<li><strong>Measure, don&#8217;t guess.<\/strong> Count tokens with the right tokenizer and log <code>usage<\/code> for every call.<\/li>\n<li><strong>Always reserve room for the answer.<\/strong> Keep <em>input + max output<\/em> below the context window with a safety margin.<\/li>\n<li><strong>Send only what helps.<\/strong> Retrieve the relevant chunks of a document instead of pasting the whole thing.<\/li>\n<li><strong>Put important things at the start or end<\/strong> of a long prompt, not buried in the middle.<\/li>\n<li><strong>Set a sensible max output.<\/strong> Too low cuts answers; too high wastes budget on rambling replies.<\/li>\n<li><strong>Plan for other languages.<\/strong> Hindi and other non-Latin scripts usually need more tokens for the same meaning.<\/li>\n<li><strong>Choose the smallest model that does the job well.<\/strong> Fewer parameters usually means faster and cheaper.<\/li>\n<\/ul>\n<\/div>\n\n\n\n<div class=\"dd-post\">\n<h2 id=\"practice\">Practice task<\/h2>\n<p>Try this before Part 3 (about 20\u201330 minutes):<\/p>\n<ol>\n<li>Run <code>count_tokens.py<\/code> (or the Node.js version) on a paragraph in English and the same paragraph translated into your own language. Calculate how many percent more tokens the translation uses.<\/li>\n<li>Change <code>token_budget.py<\/code> so it also prints <em>how many tokens are left<\/em> in the window for each request, and warns when less than 10% is free.<\/li>\n<li>Upgrade <code>trim_history.py<\/code> to use <code>tiktoken<\/code> instead of the rough <code>len(text) \/\/ 4<\/code> estimate. Do the kept messages change?<\/li>\n<li>Use <code>model_memory.py<\/code> to decide which models in the 1B\u201370B range could fit on your own computer at 4-bit precision.<\/li>\n<\/ol>\n<div class=\"dd-tip\"><strong>Bonus:<\/strong> paste a long chat (50+ messages) into a token counter. How many tokens does the history use? Now you know why long chats cost more.<\/div>\n\n<h2 id=\"faq\">FAQ: tokens, context windows and parameters<\/h2>\n<details><summary>How many words is 1,000 tokens?<\/summary><p>For normal English text, about 750 words. For code, Hindi or other languages it is usually fewer words, because they need more tokens.<\/p><\/details>\n<details><summary>What happens if my prompt is bigger than the context window?<\/summary><p>The API returns an error and nothing is generated. Some chat apps hide this by silently dropping or summarising old messages for you.<\/p><\/details>\n<details><summary>Does a bigger context window make the model smarter?<\/summary><p>No. It lets the model see more text at once, but its knowledge and reasoning come from its training and parameters. Very long inputs can even make it miss details.<\/p><\/details>\n<details><summary>Are more parameters always better?<\/summary><p>Not always. Bigger models usually know more, but a newer, well-trained small model can beat an older large one. Bigger models are also slower and more expensive.<\/p><\/details>\n<details><summary>Why are output tokens more expensive than input tokens?<\/summary><p>Input tokens can be processed in parallel, but output tokens are generated one by one, which uses more compute per token.<\/p><\/details>\n<details><summary>Can I use tiktoken for Claude or Gemini models?<\/summary><p>Only as a rough estimate. Each provider uses its own tokenizer. Use Anthropic&#8217;s or Google&#8217;s token counting API for accurate numbers.<\/p><\/details>\n\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>You now understand the three numbers behind every LLM call. <strong>Tokens<\/strong> are the pieces of text models read, write and bill. The <strong>context window<\/strong> is the working memory that must hold your input and the answer together. <strong>Parameters<\/strong> are the learned knowledge that decides a model&#8217;s quality and how much memory it needs. You also wrote code to count tokens, check budgets, trim chat history and estimate model memory.<\/p>\n<p>If you missed it, start from <a href=\"https:\/\/devdojo.co.in\/?p=215\">Part 1: What Is Generative AI and How Do LLMs Work?<\/a>. And when you are ready to see tokens and context used by AI agents, read our <a href=\"https:\/\/devdojo.co.in\/index.php\/2026\/10\/08\/openai-agents-sdk-python\/\">OpenAI Agents SDK tutorial<\/a>.<\/p>\n\n<div class=\"dd-next\"><strong>Next part \u2013 Generative AI Part 3: Your First LLM API Calls in Python and Node.js (OpenAI, Anthropic, Gemini).<\/strong> We will create API keys safely, make real calls to three providers, compare their request formats and handle errors and usage like a pro.<\/div>\n\n<div class=\"dd-cta\">\n<h3>New posts every day on DevDojo<\/h3>\n<p>Follow the full <strong>Generative AI series<\/strong> \u2013 30 parts from &#8220;what is an LLM&#8221; to building a production AI assistant. Bookmark <a href=\"https:\/\/devdojo.co.in\/\">devdojo.co.in<\/a> and leave a comment with any question about this part.<\/p>\n<\/div>\n<\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>Learn what tokens, the LLM context window and model parameters mean, with Python and Node.js code to count tokens, trim chat history and estimate memory.<\/p>\n","protected":false},"author":1,"featured_media":218,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[38],"tags":[114,117,113,44,112,116],"class_list":["post-219","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai","tag-ai-for-beginners","tag-context-window","tag-generative-ai","tag-llm","tag-series-generative-ai","tag-tokens"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"Learn what tokens, the LLM context window and model parameters mean, with Python and Node.js code to count tokens, trim chat history and estimate memory.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Lokendra\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"DevDojo - Empowering Developers\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"LLM Context Window, Tokens &amp; Parameters Explained\" \/>\n\t\t<meta property=\"og:description\" content=\"Learn what tokens, the LLM context window and model parameters mean, with Python and Node.js code to count tokens, trim chat history and estimate memory.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-10-18T18:01:33+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-10-18T18:01:34+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"LLM Context Window, Tokens &amp; Parameters Explained\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Learn what tokens, the LLM context window and model parameters mean, with Python and Node.js code to count tokens, trim chat history and estimate memory.\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BlogPosting\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/genai-series-part-2-tokens-context-window-parameters\\\/#blogposting\",\"name\":\"LLM Context Window, Tokens & Parameters Explained\",\"headline\":\"Generative AI Part 2: Tokens, Context Windows and Model Parameters\",\"author\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/author\\\/lokendra\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/devdojo.co.in\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/genai-series-part-2-tokens-context-window-parameters.jpg\",\"width\":1200,\"height\":630,\"caption\":\"Generative AI series Part 2 banner: text becomes tokens, tokens fill the context window, and an 8B-parameter LLM processes them\"},\"datePublished\":\"2026-10-18T18:01:33+00:00\",\"dateModified\":\"2026-10-18T18:01:34+00:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/genai-series-part-2-tokens-context-window-parameters\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/genai-series-part-2-tokens-context-window-parameters\\\/#webpage\"},\"articleSection\":\"AI, AI for Beginners, Context Window, Generative AI, LLM, Series: Generative AI, Tokens\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/genai-series-part-2-tokens-context-window-parameters\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/devdojo.co.in\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/category\\\/ai\\\/#listItem\",\"name\":\"AI\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/category\\\/ai\\\/#listItem\",\"position\":2,\"name\":\"AI\",\"item\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/category\\\/ai\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/genai-series-part-2-tokens-context-window-parameters\\\/#listItem\",\"name\":\"Generative AI Part 2: Tokens, Context Windows and Model Parameters\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/genai-series-part-2-tokens-context-window-parameters\\\/#listItem\",\"position\":3,\"name\":\"Generative AI Part 2: Tokens, Context Windows and Model Parameters\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/category\\\/ai\\\/#listItem\",\"name\":\"AI\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/#organization\",\"name\":\"DevDojo\",\"description\":\"Empowering Developers\",\"url\":\"https:\\\/\\\/devdojo.co.in\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/author\\\/lokendra\\\/#author\",\"url\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/author\\\/lokendra\\\/\",\"name\":\"Lokendra\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/genai-series-part-2-tokens-context-window-parameters\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/99f102f0cc9080237ce54b91304fd1b3b6fa29925cbaeba93cd796872e58b45c?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Lokendra\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/genai-series-part-2-tokens-context-window-parameters\\\/#webpage\",\"url\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/genai-series-part-2-tokens-context-window-parameters\\\/\",\"name\":\"LLM Context Window, Tokens & Parameters Explained\",\"description\":\"Learn what tokens, the LLM context window and model parameters mean, with Python and Node.js code to count tokens, trim chat history and estimate memory.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/genai-series-part-2-tokens-context-window-parameters\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/author\\\/lokendra\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/author\\\/lokendra\\\/#author\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/devdojo.co.in\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/genai-series-part-2-tokens-context-window-parameters.jpg\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/genai-series-part-2-tokens-context-window-parameters\\\/#mainImage\",\"width\":1200,\"height\":630,\"caption\":\"Generative AI series Part 2 banner: text becomes tokens, tokens fill the context window, and an 8B-parameter LLM processes them\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/genai-series-part-2-tokens-context-window-parameters\\\/#mainImage\"},\"datePublished\":\"2026-10-18T18:01:33+00:00\",\"dateModified\":\"2026-10-18T18:01:34+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/#website\",\"url\":\"https:\\\/\\\/devdojo.co.in\\\/\",\"name\":\"DevDojo\",\"description\":\"Empowering Developers\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"LLM Context Window, Tokens & Parameters Explained","description":"Learn what tokens, the LLM context window and model parameters mean, with Python and Node.js code to count tokens, trim chat history and estimate memory.","canonical_url":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BlogPosting","@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/#blogposting","name":"LLM Context Window, Tokens & Parameters Explained","headline":"Generative AI Part 2: Tokens, Context Windows and Model Parameters","author":{"@id":"https:\/\/devdojo.co.in\/index.php\/author\/lokendra\/#author"},"publisher":{"@id":"https:\/\/devdojo.co.in\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/devdojo.co.in\/wp-content\/uploads\/2026\/10\/genai-series-part-2-tokens-context-window-parameters.jpg","width":1200,"height":630,"caption":"Generative AI series Part 2 banner: text becomes tokens, tokens fill the context window, and an 8B-parameter LLM processes them"},"datePublished":"2026-10-18T18:01:33+00:00","dateModified":"2026-10-18T18:01:34+00:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/#webpage"},"isPartOf":{"@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/#webpage"},"articleSection":"AI, AI for Beginners, Context Window, Generative AI, LLM, Series: Generative AI, Tokens"},{"@type":"BreadcrumbList","@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/#listItem","position":1,"name":"Home","item":"https:\/\/devdojo.co.in\/","nextItem":{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/index.php\/category\/ai\/#listItem","name":"AI"}},{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/index.php\/category\/ai\/#listItem","position":2,"name":"AI","item":"https:\/\/devdojo.co.in\/index.php\/category\/ai\/","nextItem":{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/#listItem","name":"Generative AI Part 2: Tokens, Context Windows and Model Parameters"},"previousItem":{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/#listItem","position":3,"name":"Generative AI Part 2: Tokens, Context Windows and Model Parameters","previousItem":{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/index.php\/category\/ai\/#listItem","name":"AI"}}]},{"@type":"Organization","@id":"https:\/\/devdojo.co.in\/#organization","name":"DevDojo","description":"Empowering Developers","url":"https:\/\/devdojo.co.in\/"},{"@type":"Person","@id":"https:\/\/devdojo.co.in\/index.php\/author\/lokendra\/#author","url":"https:\/\/devdojo.co.in\/index.php\/author\/lokendra\/","name":"Lokendra","image":{"@type":"ImageObject","@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/99f102f0cc9080237ce54b91304fd1b3b6fa29925cbaeba93cd796872e58b45c?s=96&d=mm&r=g","width":96,"height":96,"caption":"Lokendra"}},{"@type":"WebPage","@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/#webpage","url":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/","name":"LLM Context Window, Tokens & Parameters Explained","description":"Learn what tokens, the LLM context window and model parameters mean, with Python and Node.js code to count tokens, trim chat history and estimate memory.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/devdojo.co.in\/#website"},"breadcrumb":{"@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/#breadcrumblist"},"author":{"@id":"https:\/\/devdojo.co.in\/index.php\/author\/lokendra\/#author"},"creator":{"@id":"https:\/\/devdojo.co.in\/index.php\/author\/lokendra\/#author"},"image":{"@type":"ImageObject","url":"https:\/\/devdojo.co.in\/wp-content\/uploads\/2026\/10\/genai-series-part-2-tokens-context-window-parameters.jpg","@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/#mainImage","width":1200,"height":630,"caption":"Generative AI series Part 2 banner: text becomes tokens, tokens fill the context window, and an 8B-parameter LLM processes them"},"primaryImageOfPage":{"@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/#mainImage"},"datePublished":"2026-10-18T18:01:33+00:00","dateModified":"2026-10-18T18:01:34+00:00"},{"@type":"WebSite","@id":"https:\/\/devdojo.co.in\/#website","url":"https:\/\/devdojo.co.in\/","name":"DevDojo","description":"Empowering Developers","inLanguage":"en-US","publisher":{"@id":"https:\/\/devdojo.co.in\/#organization"}}]},"og:locale":"en_US","og:site_name":"DevDojo - Empowering Developers","og:type":"article","og:title":"LLM Context Window, Tokens &amp; Parameters Explained","og:description":"Learn what tokens, the LLM context window and model parameters mean, with Python and Node.js code to count tokens, trim chat history and estimate memory.","og:url":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/","article:published_time":"2026-10-18T18:01:33+00:00","article:modified_time":"2026-10-18T18:01:34+00:00","twitter:card":"summary_large_image","twitter:title":"LLM Context Window, Tokens &amp; Parameters Explained","twitter:description":"Learn what tokens, the LLM context window and model parameters mean, with Python and Node.js code to count tokens, trim chat history and estimate memory."},"aioseo_meta_data":{"post_id":"219","title":"LLM Context Window, Tokens & Parameters Explained","description":"Learn what tokens, the LLM context window and model parameters mean, with Python and Node.js code to count tokens, trim chat history and estimate memory.","keywords":null,"keyphrases":{"focus":{"keyphrase":"context window","score":79},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":"LLM Context Window, Tokens & Parameters Explained","og_description":"Learn what tokens, the LLM context window and model parameters mean, with Python and Node.js code to count tokens, trim chat history and estimate memory.","og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"BlogPosting","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":0,"frequency":"default","local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"created":"2026-10-18 17:57:19","updated":"2026-10-18 18:01:34","focus_keyword":"context window","additional_keywords":null,"truseo_locale":null,"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/devdojo.co.in\/\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/devdojo.co.in\/index.php\/category\/ai\/\" title=\"AI\">AI<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tGenerative AI Part 2: Tokens, Context Windows and Model Parameters\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/devdojo.co.in\/"},{"label":"AI","link":"https:\/\/devdojo.co.in\/index.php\/category\/ai\/"},{"label":"Generative AI Part 2: Tokens, Context Windows and Model Parameters","link":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/genai-series-part-2-tokens-context-window-parameters\/"}],"_links":{"self":[{"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/posts\/219","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/comments?post=219"}],"version-history":[{"count":1,"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/posts\/219\/revisions"}],"predecessor-version":[{"id":220,"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/posts\/219\/revisions\/220"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/media\/218"}],"wp:attachment":[{"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/media?parent=219"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/categories?post=219"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/tags?post=219"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}