AI 资讯
The Developer's Guide to Picking the Right Coding LLM at Scale
The Developer's Guide to Picking the Right Coding LLM at Scale Six months ago, I was staring at our monthly AI bill — $14,000 and climbing fast. We were using the "premium" model for everything, including trivial code completions. That night, I built a small internal benchmark to figure out which models actually earn their cost. What I learned reshaped how we think about AI tooling, vendor lock-in, and what "production-ready" really means. Here's the raw truth from my testing rig, what we shipped, and how we cut costs by 70% without touching output quality. Why I Stopped Trusting Default Recommendations Every vendor says their model is the best. Every benchmark site ranks things differently. Most "best of" lists are either sponsored or built on vibes. I needed numbers that matched my actual workflow: generating Python services, debugging JavaScript race conditions, implementing TypeScript algorithms, and reviewing Go for security. So I took ten models, threw identical prompts at them, and scored them myself. No vendor PR. No cherry-picked examples. Just the same five tasks, run the same way, scored on the same rubric. Here are the ten models I tested, with their output pricing per million tokens — because at scale, that's the metric that decides whether your AI strategy is viable or a margin killer. Model Provider Output $/M DeepSeek V4 Flash DeepSeek $0.25 DeepSeek Coder DeepSeek $0.25 Qwen3-Coder-30B Qwen $0.35 DeepSeek V4 Pro DeepSeek $0.78 DeepSeek-R1 DeepSeek $2.50 Kimi K2.5 Moonshot $3.00 GLM-5 Zhipu $1.92 Qwen3-32B Qwen $0.28 Hunyuan-Turbo Tencent $0.57 Ga-Standard GA Routing $0.20 Before you ask: yes, I tested against the originals. I also tested against Global API's unified routing layer, which lets you hit any of these through one endpoint. More on that later — it became the architectural decision that actually saved us. My Benchmark Methodology (No Marketing Fluff) I built five tasks that mirror what my engineers actually do every week. Not synthetic acad
AI 资讯
Power BI DAX Essential Functions — Explained with Examples
If you’ve ever struggled with CALCULATE() or wondered why SUMX() behaves differently from SUM() , this guide is for you. DAX (Data Analysis Expressions) is the language that powers Power BI , Analysis Services , and Power Pivot — enabling dynamic calculations, filtering, and time intelligence. Below is a categorized cheat sheet of essential DAX functions , plus examples showing how to use each in real-world Power BI scenarios. Filtering & Context These functions control how filters are applied and evaluated in your calculations. Function Example Description CALCULATE() CALCULATE(SUM(Sales[Amount]), Region[Name] = "Nairobi") Changes filter context to calculate total sales for Nairobi. FILTER() FILTER(Sales, Sales[Amount] > 10000) Returns a table filtered by condition. ALL() CALCULATE(SUM(Sales[Amount]), ALL(Region)) Ignores filters on Region. REMOVEFILTERS() CALCULATE(SUM(Sales[Amount]), REMOVEFILTERS(Region)) Removes filters from Region. VALUES() VALUES(Customer[City]) Returns unique list of cities. SELECTEDVALUE() SELECTEDVALUE(Product[Category], "All") Returns selected category or “All” if none. TREATAS() TREATAS(VALUES(Temp[City]), Customer[City]) Applies one table’s values as filters on another. KEEPFILTERS() CALCULATE(SUM(Sales[Amount]), KEEPFILTERS(Product[Category] = "Electronics")) Keeps existing filters and adds new ones. ALLSELECTED() CALCULATE(SUM(Sales[Amount]), ALLSELECTED(Region)) Respects user selections in visuals. ALLEXCEPT() CALCULATE(SUM(Sales[Amount]), ALLEXCEPT(Sales, Sales[Year])) Removes all filters except Year. Aggregation Summarize or aggregate data across rows or columns. Function Example Description SUM() SUM(Sales[Amount]) Adds all sales amounts. AVERAGE() AVERAGE(Sales[Amount]) Calculates mean value. COUNT() COUNT(Customer[ID]) Counts non-blank entries. COUNTROWS() COUNTROWS(Sales) Counts rows in a table. DISTINCTCOUNT() DISTINCTCOUNT(Customer[ID]) Counts unique customers. MIN() MIN(Sales[Amount]) Finds smallest sale. MAX() MAX(Sales[Amo
AI 资讯
I built my first Robinhood Chain app as an index basket
I built a small index basket app on Robinhood Chain because I wanted to understand the developer path from the first contract deploy all the way to a working frontend. The app is intentionally plain: a user deposits Stock Tokens, which are blockchain tokens that represent real equity exposure, and receives an ERC-20 basket share. ERC-20 is Ethereum's standard token interface, so a compatible token exposes familiar methods like balanceOf , transfer , and approve . The basket share is priced from live price feeds, and the user can redeem it back into the underlying Stock Tokens. That's the part that made this interesting to me. The chain is custom, but the app path is not. I still wrote Solidity, deployed with Foundry, read contract state with viem, and wrote transactions from React with wagmi. If you've built normal web apps, think of the chain's RPC endpoint as the API base URL. A wallet is login plus a signing key. A smart contract is backend code you deploy to the chain, except you should treat it like immutable infrastructure because you don't get to hot-patch it casually later. The demo and source are here: App: https://robinhood-chain-dapp.vercel.app/ Code: https://github.com/hummusonrails/robinhood-chain-dapp-example The custom chain still feels like the EVM Robinhood Chain is a custom Arbitrum Chain, which means it runs as a dedicated chain on the stack of Arbitrum, an Ethereum scaling system. It is also EVM-compatible. EVM means Ethereum Virtual Machine, the runtime that executes Solidity contracts, so the tooling surface looks like the Ethereum developer flow many tutorials already teach. An L2, or rollup, is a chain that executes transactions separately and then posts compressed proof or transaction data back to Ethereum. Robinhood Chain uses Ethereum blobs for data availability, which is a cheaper Ethereum data lane for rollups to publish the data needed to reconstruct chain state. Gas, the metered compute fee you pay to run transactions, is paid in ETH.
AI 资讯
Generate TypeScript Types from JSON (and where the auto-generators trip up)
You've got a JSON API response and you want TypeScript interfaces for it. Here's how to generate them fast — and where the auto-generators quietly get it wrong. The fast path Paste your JSON, get interfaces: { "id" : 1 , "name" : "Ada" , "roles" : [ "admin" ], "profile" : { "active" : true } } → interface Root { id : number ; name : string ; roles : string []; profile : Profile ; } interface Profile { active : boolean ; } jsonviewertool.com/json-to-typescript does this in the browser (client-side), nesting objects into their own interfaces. Where generators trip up A generator only sees the ONE sample you give it, which causes predictable gaps: Nullable fields. If your sample has "avatar": null , the generator infers null — but the real type is probably string | null . Feed it a populated sample, or fix it by hand. Empty arrays. "tags": [] infers any[] — the element type is unknowable from an empty array. Optional fields. A field missing from your sample won't appear at all. If the API sometimes omits middleName , mark it middleName?: string . Unions. A status that's "active" in your sample becomes string , not the literal union "active" | "banned" | "pending" . Narrow it manually for the safety. Numbers that are really enums or IDs. "currency": 840 types as number ; you may want an enum or branded type. When to use a schema instead If the JSON has a JSON Schema or OpenAPI spec, generate types from that ( json-schema-to-typescript , openapi-typescript ) — it encodes nullability, optionality, and unions the raw sample can't. Sample-based generation is for quick throwaway typing; schema-based is for anything you'll maintain. Rule of thumb Generate from a sample to skip the boilerplate, then read every field — the generator gives you a draft, not a contract. Nullability and optional fields are where the runtime bugs hide.
AI 资讯
Offline Sync in the Browser Without a Framework
I've been building apps with IndexedDB for years. The local part works fine — store data, query it, show it on screen. The hard part is keeping that data in sync with a server when the network comes and goes. Most tutorials show you how to build an offline app with a framework. Firebase, RxDB, WatermelonDB. Those work, but they bring their own abstractions, their own sync protocols, their own opinions. I wanted something simpler. A database with a sync API that doesn't dictate how my backend works. Here's the setup I landed on. npm: npm install ctrodb Docs: ctrodb.vercel.app/docs/sync/overview What We're Building A notes app that works offline. Create and edit notes on the train, in a tunnel, on a plane. When the network comes back, everything syncs automatically. The database is ctrodb (zero-dependency, browser-based). The backend is anything that speaks HTTP. Step 1: Database Setup import { Database , syncPlugin , HttpTransport } from " ctrodb " const db = new Database ({ name : " notes-app " , schema : { version : 1 , collections : { notes : { fields : { title : { type : " string " , required : true }, body : { type : " string " }, updatedAt : { type : " string " , default : () => new Date (). toISOString () }, }, indexes : [{ field : " updatedAt " }], }, }, }, }) await db . connect () Every collection you want to sync needs a timestamp field. The sync engine uses it to order changes and detect conflicts. Plugins are passed in the Database constructor via plugins array: const transport = new HttpTransport ({ url : " https://api.myapp.com/sync " , }) const db = new Database ({ name : " notes-app " , schema : { ... }, plugins : [ syncPlugin ({ transport })], }) await db . connect () The transport takes a single base URL and appends /push and /pull automatically. The sync plugin hooks into every write operation and records it in the change log. The plugin exposes devtools that take the database instance as their first argument: import { inspectSyncQueue , retryFaile
AI 资讯
Conditional Statements in JavaScript
Conditional Statements Conditional statements allow JavaScript to execute different blocks of code based on whether a condition is true or false. if - The if statement executes a block of code only if the condition is true. if...else - Use if...else when you want one block of code to run if the condition is true and another block if it's false. if...else if...else - Use this when you have multiple conditions to check. switch statement - The switch statement is used when you have many possible values for one variable. Nested if statement - You can also write an if statement inside another if. Ternary Operator - An optimized one-line shorthand for standard if...else blocks ** If Statement ** let age = 20 ; if ( age >= 18 ) { console . log ( " Eligible to vote " ); } //Output: Eligible to vote ** if else Statement ** let age = 16 ; if ( age >= 18 ) { console . log ( " Eligible to vote " ); } else { console . log ( " Not eligible to vote " ); } // Output: Not eligible to vote ** if ... else if ... else ** let marks = 85 ; if ( marks >= 90 ) { console . log ( " Grade A " ); } else if ( marks >= 75 ) { console . log ( " Grade B " ); } else if ( marks >= 50 ) { console . log ( " Grade C " ); } else { console . log ( " Fail " ); } // Output: Grade B ** switch statement ** let day = 3 ; switch ( day ) { case 1 : console . log ( " Monday " ); break ; case 2 : console . log ( " Tuesday " ); break ; case 3 : console . log ( " Wednesday " ); break ; default : console . log ( " Invalid Day " ); } // Output: Wednesday // Important: The break statement stops the execution after the matching case.We must compulsory to use break statement because if you don't use break, JavaScript will continue executing the next cases even the output is correct. ** Nested if Statement ** let age = 20 ; let hasLicense = true ; if ( age >= 18 ) { if ( hasLicense ) { console . log ( " You can drive. " ); } } // Output: You can drive. ** Ternary Operator ** let isLoggedIn = true ; let systemMessage = is
开发者
A Beginner's Guide to Installing and Using Node.js on Windows
Have you ever wondered how massive modern platforms like Netflix, PayPal, and LinkedIn handle millions of users simultaneously without crashing? The secret weapon behind much of the modern web is Node.js. Traditionally, JavaScript—the language that makes websites interactive—could only run inside a web browser like Chrome or Edge. Node.js changed the game by freeing JavaScript from the browser, allowing it to run directly on your computer. This means you can use it to build backend servers, automate boring computer tasks, or run powerful development tools. If you are intimidated by coding, don't worry. This guide will take you from zero to running your very first Node.js program on Windows, step-by-step. Prerequisites Before we begin, you only need two things: A computer running Windows 10 or 11. An active internet connection to download the installer. No prior coding experience or command-line knowledge is required! Step-by-Step Instructions Download the Node.js Installer First, we need to grab the official installation file. Open your web browser and go to the official website: nodejs.org. You will see two primary options to download. Always choose the LTS (Long Term Support) version. The LTS version is heavily tested, stable, and less likely to give you unexpected errors. Click the Windows Installer button to download the .msi file to your computer. Run the Setup Wizard Once the download finishes, navigate to your Downloads folder and double-click the file to open the setup wizard. Click Next on the welcome screen. Accept the license agreement and click Next. Leave the default installation folder as it is (C:\Program Files\nodejs) and click Next. On the "Custom Setup" screen, leave everything at its default and click Next. Important Step: You will see a checkbox that asks to "Automatically install the necessary tools." Leave this unchecked for now to keep your setup simple and fast. Click Next. Finally, click Install. If Windows asks for permission to make change
AI 资讯
Docker Volumes vs Bind Mounts: Where Your Data Actually Lives
A container's writable layer feels like a filesystem, and that's exactly the trap. Write a database into it, remove the container, and the data is gone — no warning, no recovery. If you want anything to survive docker rm , it has to live outside the container, and Docker gives you three ways to do that: named volumes, bind mounts, and tmpfs. Knowing which one to reach for is most of the battle. Why the writable layer betrays you Every running container gets a thin read-write layer stacked on top of its image layers. It looks persistent because you can docker exec in and see your files. But that layer is bound to the container's lifecycle. docker run --name scratch alpine sh -c 'echo hello > /data.txt; cat /data.txt' # hello docker rm scratch # the layer — and /data.txt — no longer exists There's no "oops." The writable layer is discarded with the container. Persistence is not a default you get; it's a decision you make. That decision is a volume, a bind mount, or tmpfs. Named volumes: the default for state A named volume is storage that Docker creates and manages for you. You give it a name, Docker keeps the actual bytes under its own directory, and you never have to care where that is. docker volume create pgdata docker run -d --name db \ --mount type = volume,source = pgdata,target = /var/lib/postgresql/data \ postgres:16 The container writes to /var/lib/postgresql/data , but those bytes land in a Docker-managed location on the host. Remove and recreate the container against the same volume and the data is still there. docker rm -f db docker run -d --name db \ --mount type = volume,source = pgdata,target = /var/lib/postgresql/data \ postgres:16 # same data, new container Where do the bytes actually live? Under Docker's data root, typically /var/lib/docker/volumes/<name>/_data : docker volume inspect pgdata --format '{{ .Mountpoint }}' # /var/lib/docker/volumes/pgdata/_data The point is that you're not supposed to reach into that path directly — Docker owns it. You
AI 资讯
Markov Chain Monte Carlo: Theoretical Foundations
Adapted from an appendix of my MS thesis. Markov Chain Monte Carlo Almost as soon as computers were invented, they were used for simulation. Markov chain Monte Carlo (MCMC) was invested as Los Alamos, Metropolis et al (1953) simulated a liquid in equilibrium with its gas phase. Their tour de force was the realization that they did not need to simulate the exact dynamics, they only needed to simulate some Markov chain with the same equilibrium distribution. The Metropolis algorithm was widely used by chemists and physicists, but was not widely known among statisticians until after 1990. Hastings (1970) generalized the Metropolis algorithm, and simulations following his scheme are said to use the Metropolis-Hastings (MH) algorithm [1]. A special case of the MH algorithm was introduced by Geman et al (1984) discussing optimization to find the posterior mode rather than simulation. Algorithms following their scheme are said to use the Gibbs sampler. It took some time for the spatial statistics community to understand that the Gibbs sampler simulated the posterior distribution, thus enabling full Bayesian inference of all kinds. Gelfand et al (1990) made the wider Bayesian community aware of the Gibbs sampler, and then it was rapidly realized that most Bayesian inference could be done using MCMC, whereas very little could be done without MCMC. Green (1995) generalized the MH algorithm as much as it could be generalized [1]. Theoretical Foundations A sequence X 1 , X 2 , … of random elements of some set is a Markov chain if the conditional distribution of X n + 1 given X 1 , … , X n depends on X n only. The set in which the X i take values is called the state space of the Markov chain. A Markov chain has stationary transition probabilities if the conditional distribution of X n + 1 given X n does not depend on n . This is the main kind of Markov chain of interest in MCMC. The joint distribution of a Markov chain is determined by the following [1]. The ma
AI 资讯
Two weekends into a Chrome side panel: the four state bugs that took longer than the UI
I shipped the first public build of a Chrome extension two weekends ago. The marketing-ready UI took me about six hours. The four state bugs below took me the rest of those two weekends, plus parts of the following week. I am writing this down because every reviewer of "I built an X in Y hours" posts seems to skip the state-model half, and the state-model half is where the actual time goes. The extension A sidebar that lives in Chrome's side panel API. You highlight text or screenshot a region on any page, the sidebar lets you pick a destination AI tab (ChatGPT / Claude / Gemini / a custom one) and forwards the content with a small wrapper prompt. That is the whole product description. The interesting part is what happens when a user does it twice. Bug 1: the destination you "logged into" is not the destination the message lands in First failure I caught: user has two ChatGPT tabs open, one workspace, one personal. The extension forwards to whichever tab was last focused. The user sees the message arrive in the workspace, replies there, then realizes the context they wanted to capture is on the personal tab. Fix: every AI destination registers a stable tab id at extension boot, not at click time. The forwarding logic walks the registry, not the focused window. Took a morning to redesign, an afternoon to migrate existing flows. Lesson: tab identity is not the same as window focus. Chrome's chrome.tabs.query({active: true}) returns the active tab. The active tab is not necessarily the destination the user has in their head. Bug 2: the screenshot is from before the user edited it User takes a screenshot of a code block, opens the sidebar, hits "annotate", drags a red box around lines 12-15, hits send. The annotation worked. But the underlying screenshot bytes were captured at the moment the toolbar first appeared, before the user could draw the box. Fix: the sidebar cannot trust that the screenshot in memory is the screenshot the user is looking at. Either re-capture o
AI 资讯
How to usar Docker networks na pratica
Quando voce cria um container e depois outro, eles podem nao se enxergar. O motivo quase sempre e a rede. Entender os tipos de rede que o Docker oferece resolve isso de uma vez. Comece listando as redes que ja existem no seu Docker. docker network ls A rede bridge e a rede host vem de fabrica. Nenhuma delas oferece resolucao de nomes entre containers. Para isso voce precisa criar a sua propria rede. docker network create minha-rede Agora os containers que entrarem nessa rede conseguem se comunicar pelo nome do container. docker run -d --name app1 --network minha-rede nginx docker run -d --name app2 --network minha-rede alpine sleep 3600 Teste a comunicacao. docker exec app2 ping app1 -c 2 O ping funciona. O DNS interno do Docker resolve app1 para o IP interno do container. Isso resolve 90% dos problemas de comunicacao. A rede bridge padrao nao tem esse recurso. Crie sua propria rede sempre que precisar que containers se enxerguem. Agora a rede host. Ela elimina o isolamento de rede. O container usa a placa do host diretamente, sem NAT e sem mapeamento de porta. docker run -d --name web-host --network host nginx O nginx fica acessivel em http://localhost:80 direto. Sem -p 80:80. Mas so um container pode usar cada porta, porque a porta e a do host de verdade. Para ambientes com mais de uma maquina, existe a rede overlay. Ela precisa do Docker Swarm ou de um cluster. docker swarm init docker network create -d overlay rede-overlay docker service create --name api --network rede-overlay --replicas 3 nginx Os containers em maquinas diferentes se enxergam pelo nome como se estivessem na mesma maquina. No dia a dia, a rede bridge personalizada resolve quase todo caso de uso. Host e para performance ou casos especificos. Overlay e para quando voce escala para mais de uma maquina. That's all for now. Thanks for reading!
开发者
Checkout my new post about Typescript.
The Complete TypeScript Mastery Guide Navneet Verma Navneet Verma Navneet Verma Follow Jul 10 The Complete TypeScript Mastery Guide # typescript # webdev # systemdesign # tutorial 5 reactions Add Comment 54 min read
AI 资讯
The Complete TypeScript Mastery Guide
Learn TypeScript From First Principles to Senior/Staff-Level Production Engineering If you searched for how to learn TypeScript properly — not just the syntax, but the thinking behind it — this guide is built for that. Most TypeScript tutorials stop at "here's an interface, here's a generic." This one goes further: it's a single, exhaustive TypeScript tutorial and reference that walks through the type system, object-oriented programming, generics, async programming, design patterns, SOLID and DRY principles, error handling, testing, and the tooling that real production teams run in CI — the same TypeScript best practices used at top-tier engineering organizations. Whether you're a beginner looking for a structured TypeScript for beginners path, or an experienced JavaScript developer making the jump to advanced TypeScript and system design, you can read this end to end or jump straight to the section you need using the linked table of contents below. Table of Contents 1. Introduction — What Is TypeScript & Why It Exists 2. Installation, Setup & tsconfig.json Deep Dive 3. Variables & the Complete Type System 4. Functions — Every Form, Overloads, this , and Best Practices 5. Arrays & Tuples 6. Objects & Type Aliases 7. Interfaces 8. Enums & Literal Types 9. Union, Intersection & Discriminated Unions 10. Type Narrowing, Assertions & Type Guards 11. Classes & Object-Oriented Programming 12. Generics — Basic to Advanced 13. Modules, Namespaces & Project Structure 14. Asynchronous Programming — Event Loop to Production Patterns 15. Advanced/Utility Types & the Type-Level Programming Toolkit 16. Design Patterns in TypeScript 17. SOLID, DRY, KISS, YAGNI — Principles Applied With Real TS Code 18. Error Handling Strategies 19. Testing TypeScript 20. Tooling, Linting, Build Systems & CI/CD for Production TS 21. Performance, Compiler Internals & Scaling Large Codebases 22. Interview Cheat Sheet (Expanded) 23. One-Page Quick Revision Sheet 1. Introduction — What Is TypeScript & W
AI 资讯
HowTo: Let's install lots of browsers on Linux!
Here we're going to cover the installation steps of Browsers in Linux - specifically, Debian GNU/Linux . We're covering the procedural steps for this in Debian Testing (Forkey), which is already beginning the gleanings of what will become Debian 14. At the time of writing,the current kernel version is 7.0.13+deb14-amd64. Daily drivers will likely be along the lines of Vivaldi, Firefox, Lagrange, and Brave Browser, and in no particular order. Any others will be mostly for particular reasons like, testing, curiosity, Etc., but some specialized products like the Tor browser, which focus on privacy are also covered. This list is by no means complete, but there's a bunch of them we cover, so let's jump right in! I can haz #Cheezburgerz? 🍔 🍟 Well, let's see... First up is the first rate and fully featured Vivaldi, built on top of the open source Chromium, as are so many others in this list. Vivaldi Manual setup of the Vivaldi Linux repos - According to their website, "you no longer need to do this. After downloading a Linux package and installing it our Linux update repositories will be configured automatically for you to receive updates." That's awfully nice, so visit the download page above and get the .deb package: ~# mkdir -pv /usr/local/packages/vivaldi ; cd /usr/local/packages/vivaldi ~# wget https://downloads.vivaldi.com/stable/vivaldi-stable_8.1.4087.48-1_amd64.deb ~# apt install ./vivaldi * .deb That's it! You're ready to go now. Next up... Firefox ~# apt update && apt install firefox-esr There's none of this messing about anymore with softforks and trying to remember their names...'IceCat?', 'IceWeasel?'. The Trademark issues over branding have been resolved (and that's a good thing). The one thing you might want to look into is SeaMonkey , which combines the Browser with an email client (like Thunderbird), an RSS Reader, IRC client, and a few other goodies. Brave Browser ~# apt install curl ~# curl -fsSLo /usr/share/keyrings/brave-browser-archive-keyring.gpg ht
AI 资讯
Why Your EWS Impersonation Suddenly Stopped Working (And It's Probably Not Throttling)
Two months ago I picked up a ticket that looked routine: a job that reads mailbox data from Microsoft 365 through EWS, running fine for over a year, started failing on a subset of mailboxes in one tenant. Same app registration, same code path, same service account. The error in the logs pointed at throttling, so that's where the admin had already spent three days looking. Wrong direction. The actual cause had nothing to do with throttling budgets. This mix-up happens constantly right now, and it's worth understanding why, because the fix for one problem does nothing for the other, and chasing the wrong one wastes days. TL;DR: if your EWS failures don't scale with request volume, stop tuning throttling and go check your Application Access Policy scope groups instead. What EWS throttling actually looks like Exchange Online throttles EWS the same way it always has: budget-based. Every account gets a policy (the default is EwsDefaultThrottlingPolicy , but plenty of tenants layer custom ones on top) that tracks a slowly-refilling budget rather than a simple call count. When you overspend it, you get back a 503 or 429 with an X-MS-Diagnostics header telling you which budget got exhausted, usually the connection count or the concurrent-request limit. The tell for real throttling is consistency. It scales with load, correlates with concurrency and batch size, and clears up within minutes once you back off. If you graph failure rate against request volume, you'll see a clean relationship. If you double your batch size, failures increase. If you throttle yourself proactively (respecting Retry-After , staying under EWSFindCountLimit for FindItem calls), it mostly goes away. That correlation is the whole diagnostic test. If your failures don't scale with volume, you're not looking at a throttling problem, no matter what the error message on the surface says. What actually changed Over the past year or so, Microsoft tightened enforcement in two places that both produce errors ea
AI 资讯
Why Your Application Needs Observability: Building a Self-Hosted Observability Pipeline with the LGTM Stack (Loki, Grafana, Tempo, Mimir)
Understanding Observability with the LGTM Stack From "what happened last night?" to "here's exactly what happened and why" — in under 5 minutes Table of Contents Introduction What Is Observability? The Three Pillars of Observability Metrics Logs Traces Why You Need All Three Together The LGTM Stack Architecture: How It All Fits Together OpenTelemetry: The Instrumentation Standard The OTel Collector: The Brain of the Pipeline Loki: Log Aggregation Tempo: Distributed Tracing Mimir: Metrics at Scale Grafana: Connecting the Dots Conclusion Introduction Let me tell you a story that probably sounds familiar. It's 2 AM on a Sunday. Your API is slow. Users are complaining. But you're not at your desk — you're in a Sleeping, or just living your life. You have no idea it's even happening. The next morning you walk into the office and your boss meets you at the door. "Hey, the API was really slow yesterday around 2 AM. What happened?" And you're stuck. Completely stuck. You pull up the server logs — it's a wall of unformatted text. Maybe the issue already fixed itself. Maybe the container restarted overnight and the logs are gone. You weren't there, and your system left no trail. So you say the thing every developer dreads saying: "I don't know. I'll look into it." Now imagine the exact same situation — but this time you have observability set up. You open your dashboard, set the time range to yesterday 2 AM, and within two minutes you can see everything. Response times spiked to 4 seconds. The database connection pool got exhausted. And it started the exact moment a scheduled batch job kicked off and hammered the DB with hundreds of queries at once. You have a graph. You have traces. You have the exact log line that caused it. You walk back to your boss with your laptop: "Here's what happened and here's the fix." That's observability. Your system tells its own story — even when you're not watching. That's what this blog is about. I'll walk you through what observability actua
AI 资讯
How a Transformer Plays Tic-Tac-Toe
An interactive guide to the architecture behind modern language models. Instead of predicting the next word, this Transformer predicts the next move in a game of fading Tic-Tac-Toe—making every step of the model easy to visualize and understand. Play the game, inspect every matrix multiplication, and watch tokens flow through the network in real time. What's covered Tokenization and embeddings Learned positional encoding Self-attention (Q, K, V) Multi-head attention Causal masking and softmax Residual connections and layer normalization MLP (feed-forward network) Unembedding and sampling Model ablations (no positional encoding, no causal mask, no MLP, no residual stream) Includes interactive visualizations for every stage of the Transformer pipeline - from input tokens to the final prediction. https://sbondaryev.dev/articles/transformer
开发者
How to Make Rank Math Sitemap Pages Load Faster
One common issue on WordPress websites with a large number of posts is that the Rank Math XML Sitemap can become slow to load. This happens because the sitemap is generated dynamically every time a visitor or search engine bot requests it. A simple solution is to use a static sitemap cache , allowing the web server to serve pre-generated XML files directly without executing PHP for every request. This significantly reduces server load and improves crawling performance. Benefits of Using a Static Sitemap Using a static sitemap cache provides several advantages: Faster sitemap loading times. Lower CPU and PHP worker usage. Improved crawling efficiency for Google and other search engines. Ideal for websites with thousands or even millions of URLs. Reduced server load when search engine bots frequently request sitemap files. 1. Setting RankMath Sitemap Cache The first step is to enable static sitemap generation using the Rank Math Sitemap Tweak plugin. The plugin automatically creates static copies of your XML sitemaps and stores them in the following directory: /wp-content/uploads/rank-math/ Instead of generating the sitemap dynamically through WordPress, your web server can serve these static files directly. 2. Configure Apache (.htaccess) If your website is running on Apache , add the following rules to your .htaccess file. # ========================== # XML cache # ========================== RewriteCond %{REQUEST_METHOD} GET RewriteCond %{QUERY_STRING} ^$ RewriteCond %{HTTP:Cookie} !wordpress_logged_in RewriteCond %{DOCUMENT_ROOT}/wp-content/uploads/rank-math/%{HTTP_HOST}%{REQUEST_URI} -f RewriteRule ^(.*)$ /wp-content/uploads/rank-math/%{HTTP_HOST}/$1 [L] These rules check whether a cached sitemap file exists. If it does, Apache serves the static file immediately without loading WordPress. 3. Configure Nginx If your server is using Nginx , add the following configuration inside your server block. # # Static cache # location / { try_files \ /wp-content/uploads/rank-
AI 资讯
How to Put a Local Service on the Public Internet with FRP (Without Losing Your Mind Over Config Files)
The problem every self-hoster hits You built something. A local API. A Minecraft world for your friends. A self-hosted dashboard. An ERP running on the office machine. It works great — on your LAN. The moment you want someone outside to reach it, the fun begins: Port forwarding? Good luck if you're behind CGNAT, a corporate firewall, or an ISP that doesn't give you a public IP. VPN? Now every person who wants access has to install a client, join a network, and stay connected. Overkill for "let me show you this one page." Cloud deploy? Now you're maintaining two environments, paying for a VPS you didn't need, and shipping data somewhere it doesn't have to live. What most people actually want is simpler: take this one local port, give it a public address, done. That's exactly what FRP does. What FRP is FRP (Fast Reverse Proxy) is an open-source tool by fatedier that exposes a local service behind a NAT or firewall to the public internet. It's battle-tested, written in Go, and has been the go-to answer in self-hosting communities for years. The model is clean — two pieces: frps (the server) — runs on a machine with a public IP (a $5 VPS is plenty). frpc (the client) — runs on your local machine, the one with the service you want to expose. The client opens an outbound tunnel to the server. The server listens on a public port and forwards traffic back through the tunnel. NAT and firewalls don't matter because the connection is initiated from inside . [Visitor] → [frps on public VPS:7000] ⇄ tunnel ⇄ [frpc on your laptop] → [localhost:8080] That's the whole idea. It works for TCP, UDP, HTTP, HTTPS. People run Minecraft servers, remote desktops, internal dashboards, and dev previews through it every day. The catch: config files FRP works great. The friction isn't the protocol — it's the workflow . To run frpc , you write a TOML/INI config file: serverAddr = "203.0.113.10" serverPort = 7000 auth.token = "your-secret-key" [[proxies]] name = "my-web" type = "tcp" localIP = "1
AI 资讯
Improve WordPress Server Response Time by Optimizing Apache and Nginx Configuration
One of the most important performance metrics for a WordPress website is Server Response Time, commonly measured as Time to First Byte (TTFB). While caching plugins like WP Rocket significantly improve performance, many server configurations still route every request through PHP before serving the cached page. In reality, cached HTML files can be delivered directly by the web server (Apache or Nginx), completely bypassing PHP and WordPress. This approach reduces CPU usage, lowers the PHP-FPM workload, and improves overall server response time. This guide explains how to optimize both Apache (.htaccess) and Nginx so they can serve WP Rocket's static HTML cache directly. Why Is This Optimization Important? By default, a typical WordPress request follows this flow: Visitor │ ▼ Apache/Nginx │ ▼ PHP │ ▼ WordPress │ ▼ WP Rocket Cache │ ▼ HTML Response Even when a page has already been cached, the request still passes through PHP before the cached content is returned. With the following configuration, the request flow becomes: Visitor │ ▼ Apache/Nginx │ ▼ WP Rocket HTML Cache │ ▼ HTML Response PHP and WordPress are only executed when a cached file does not exist. Benefits Lower Time to First Byte (TTFB) Reduced CPU usage Less PHP-FPM processing Better performance during traffic spikes Ideal for VPS and dedicated servers Improved scalability with minimal configuration changes Apache (.htaccess) Optimization If your server runs Apache, insert the following block inside the WordPress rewrite section, immediately after: RewriteBase / and before: RewriteRule ^index\.php$ - [L] The resulting configuration should look like this: # BEGIN WordPress # Die Anweisungen (Zeilen) zwischen „BEGIN WordPress“ und „END WordPress“ sind # dynamisch generiert und sollten nur über WordPress-Filter geändert werden. # Alle Änderungen an den Anweisungen zwischen diesen Markierungen werden überschrieben. < IfModule mod_rewrite.c > RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Autho