A year of improving Node.js compatibility in Cloudflare Workers

Post Syndicated from James M Snell original https://blog.cloudflare.com/nodejs-workers-2025/

We’ve been busy.

Compatibility with the broad JavaScript developer ecosystem has always been a key strategic investment for us. We believe in open standards and an open web. We want you to see Workers as a powerful extension of your development platform with the ability to just drop code in that Just Works. To deliver on this goal, the Cloudflare Workers team has spent the past year significantly expanding compatibility with the Node.js ecosystem, enabling hundreds (if not thousands) of popular npm modules to now work seamlessly, including the ever popular express framework.

We have implemented a substantial subset of the Node.js standard library, focusing on the most commonly used, and asked for, APIs. These include:

Each of these has been carefully implemented to approximate Node.js’ behavior as closely as possible where feasible. Where matching Node.js‘ behavior is not possible, our implementations will throw a clear error when called, rather than silently failing or not being present at all. This ensures that packages that check for the presence of these APIs will not break, even if the functionality is not available.

In some cases, we had to implement entirely new capabilities within the runtime in order to provide the necessary functionality. For node:fs, we added a new virtual file system within the Workers environment. In other cases, such as with node:net, node:tls, and node:http, we wrapped the new Node.js APIs around existing Workers capabilities such as the Sockets API and fetch.

Most importantly, all of these implementations are done natively in the Workers runtime, using a combination of TypeScript and C++. Whereas our earlier Node.js compatibility efforts relied heavily on polyfills and shims injected at deployment time by developer tooling such as Wrangler, we are moving towards a model where future Workers will have these APIs available natively, without need for any additional dependencies. This not only improves performance and reduces memory usage, but also ensures that the behavior is as close to Node.js as possible.

The networking stack

Node.js has a rich set of networking APIs that allow applications to create servers, make HTTP requests, work with raw TCP and UDP sockets, send DNS queries, and more. Workers do not have direct access to raw kernel-level sockets though, so how can we support these Node.js APIs so packages still work as intended? We decided to build on top of the existing managed Sockets and fetch APIs. These implementations allow many popular Node.js packages that rely on networking APIs to work seamlessly in the Workers environment.

Let’s start with the HTTP APIs.

HTTP client and server support

From the moment we announced that we would be pursuing Node.js compatibility within Workers, users have been asking specifically for an implementation of the node:http module. There are countless modules in the ecosystem that depend directly on APIs like http.get(...) and http.createServer(...).

The node:http and node:https modules provide APIs for creating HTTP clients and servers. We have implemented both, allowing you to create HTTP clients using http.request() and servers using http.createServer(). The HTTP client implementation is built on top of the Fetch API, while the HTTP server implementation is built on top of the Workers runtime’s existing request handling capabilities.

The client side is fairly straightforward:

import http from 'node:http';

export default {
  async fetch(request) {
    return new Promise((resolve, reject) => {
      const req = http.request('http://example.com', (res) => {
        let data = '';
        res.setEncoding('utf8');
        res.on('data', (chunk) => {
          data += chunk;
        });
        res.on('end', () => {
          resolve(new Response(data));
        });
      });
      req.on('error', (err) => {
        reject(err);
      });
      req.end();
    });
  }
}

The server side is just as simple but likely even more exciting. We’ve often been asked about the possibility of supporting Express, or Koa, or Fastify within Workers, but it was difficult to do because these were so dependent on the Node.js APIs. With the new additions it is now possible to use both Express and Koa within Workers, and we’re hoping to be able to add Fastify support later. 

import { createServer } from "node:http";
import { httpServerHandler } from "cloudflare:node";

const server = createServer((req, res) => {
  res.writeHead(200, { "Content-Type": "text/plain" });
  res.end("Hello from Node.js HTTP server!");
});

export default httpServerHandler(server);

The httpServerHandler() function from the cloudflare:node module integrates the HTTP server with the Workers fetch event, allowing it to handle incoming requests.

The node:dns module

The node:dns module provides an API for performing DNS queries. 

At Cloudflare, we happen to have a DNS-over-HTTPS (DoH) service and our own DNS service called 1.1.1.1. We took advantage of this when exposing node:dns in Workers. When you use this module to perform a query, it will just make a subrequest to 1.1.1.1 to resolve the query. This way the user doesn’t have to think about DNS servers, and the query will just work.

The node:net and node:tls modules

The node:net module provides an API for creating TCP sockets, while the node:tls module provides an API for creating secure TLS sockets. As we mentioned before, both are built on top of the existing Workers Sockets API. Note that not all features of the node:net and node:tls modules are available in Workers. For instance, it is not yet possible to create a TCP server using net.createServer() yet (but maybe soon!), but we have implemented enough of the APIs to allow many popular packages that rely on these modules to work in Workers.

import net from 'node:net';
import tls from 'node:tls';

export default {
  async fetch(request) {
    const { promise, resolve } = Promise.withResolvers();
    const socket = net.connect({ host: 'example.com', port: 80 },
        () => {
      let buf = '';
      socket.setEncoding('utf8')
      socket.on('data', (chunk) => buf += chunk);
      socket.on('end', () => resolve(new Response('ok'));
      socket.end();
    });
    return promise;
  }
}

A new virtual file system and the node:fs module

What does supporting filesystem APIs mean in a serverless environment? When you deploy a Worker, it runs in Region:Earth and we don’t want you needing to think about individual servers with individual file systems. There are, however, countless existing applications and modules in the ecosystem that leverage the file system to store configuration data, read and write temporary data, and more.

Workers do not have access to a traditional file system like a Node.js process does, and for good reason! A Worker does not run on a single machine; a single request to one worker can run on any one of thousands of servers anywhere in Cloudflare’s global network. Coordinating and synchronizing access to shared physical resources such as a traditional file system harbor major technical challenges and risks of deadlocks and more; challenges that are inherent in any massively distributed system. Fortunately, Workers provide powerful tools like Durable Objects that provide a solution for coordinating access to shared, durable state at scale. To address the need for a file system in Workers, we built on what already makes Workers great.

We implemented a virtual file system that allows you to use the node:fs APIs to read and write temporary, in-memory files. This virtual file system is specific to each Worker. When using a stateless worker, files created in one request are not accessible in any other request. However, when using a Durable Object, this temporary file space can be shared across multiple requests from multiple users. This file system is ephemeral (for now), meaning that files are not persisted across Worker restarts or deployments, so it does not replace the use of the Durable Object Storage mechanism, but it provides a powerful new tool that greatly expands the capabilities of your Durable Objects.

The node:fs module provides a rich set of APIs for working with files and directories:

import fs from 'node:fs';

export default {
  async fetch(request) {
    // Write a temporary file
    await fs.promises.writeFile('/tmp/hello.txt', 'Hello, world!');

    // Read the file
    const data = await fs.promises.readFile('/tmp/hello.txt', 'utf-8');

    return new Response(`File contents: ${data}`);
  }
}

The virtual file system supports a wide range of file operations, including reading and writing files, creating and removing directories, and working with file descriptors. It also supports standard input/output/error streams via process.stdin, process.stdout, and process.stderr, symbolic links, streams, and more.

While the current implementation of the virtual file system is in-memory only, we are exploring options for adding persistent storage in the future that would link to existing Cloudflare storage solutions like R2 or Durable Objects. But you don’t have to wait on us! When combined with powerful tools like Durable Objects and JavaScript RPC, it’s certainly possible to create your own general purpose, durable file system abstraction backed by sqlite storage.

Cryptography with node:crypto

The node:crypto module provides a comprehensive set of cryptographic functionality, including hashing, encryption, decryption, and more. We have implemented a full version of the node:crypto module, allowing you to use familiar cryptographic APIs in your Workers applications. There will be some difference in behavior compared to Node.js due to the fact that Workers uses BoringSSL under the hood, while Node.js uses OpenSSL. However, we have strived to make the APIs as compatible as possible, and many popular packages that rely on node:crypto now work seamlessly in Workers.

To accomplish this, we didn’t just copy the implementation of these cryptographic operations from Node.js. Rather, we worked within the Node.js project to extract the core crypto functionality out into a separate dependency project called ncrypto that is used – not only by Workers but Bun as well – to implement Node.js compatible functionality by simply running the exact same code that Node.js is running.

import crypto from 'node:crypto';

export default {
  async fetch(request) {
    const hash = crypto.createHash('sha256');
    hash.update('Hello, world!');
    const digest = hash.digest('hex');

    return new Response(`SHA-256 hash: ${digest}`);
  }
}

All major capabilities of the node:crypto module are supported, including:

  • Hashing (e.g., SHA-256, SHA-512)

  • HMAC

  • Symmetric encryption/decryption

  • Asymmetric encryption/decryption

  • Digital signatures

  • Key generation and management

  • Random byte generation

  • Key derivation functions (e.g., PBKDF2, scrypt)

  • Cipher and Decipher streams

  • Sign and Verify streams

  • KeyObject class for managing keys

  • Certificate handling (e.g., X.509 certificates)

  • Support for various encoding formats (e.g., PEM, DER, base64)

  • and more…

Process & Environment

In Node.js, the node:process module provides a global object that gives information about, and control over, the current Node.js process. It includes properties and methods for accessing environment variables, command-line arguments, the current working directory, and more. It is one of the most fundamental modules in Node.js, and many packages rely on it for basic functionality and simply assume its presence. There are, however, some aspects of the node:process module that do not make sense in the Workers environment, such as process IDs and user/group IDs which are tied to the operating system and process model of a traditional server environment and have no equivalent in the Workers environment.

When nodejs_compat is enabled, the process global will be available in your Worker scripts or you can import it directly via import process from 'node:process'. Note that the process global is only available when the nodejs_compat flag is enabled. If you try to access process without the flag, it will be undefined and the import will throw an error.

Let’s take a look at the process APIs that do make sense in Workers, and that have been fully implemented, starting with process.env.

Environment variables

Workers have had support for environment variables for a while now, but previously they were only accessible via the env argument passed to the Worker function. Accessing the environment at the top-level of a Worker was not possible:

export default {
  async fetch(request, env) {
    const config = env.MY_ENVIRONMENT_VARIABLE;
    // ...
  }
}

With the new process.env implementation, you can now access environment variables in a more familiar way, just like in Node.js, and at any scope, including the top-level of your Worker:

import process from 'node:process';
const config = process.env.MY_ENVIRONMENT_VARIABLE;

export default {
  async fetch(request, env) {
    // You can still access env here if you need to
    const configFromEnv = env.MY_ENVIRONMENT_VARIABLE;
    // ...
  }
}

Environment variables are set in the same way as before, via the wrangler.toml or wrangler.jsonc configuration file, or via the Cloudflare dashboard or API. They may be set as simple key-value pairs or as JSON objects:

{
  "name": "my-worker-dev",
  "main": "src/index.js",
  "compatibility_date": "2025-09-15",
  "compatibility_flags": [
    "nodejs_compat"
  ],
  "vars": {
    "API_HOST": "example.com",
    "API_ACCOUNT_ID": "example_user",
    "SERVICE_X_DATA": {
      "URL": "service-x-api.dev.example",
      "MY_ID": 123
    }
  }
}

When accessed via process.env, all environment variable values are strings, just like in Node.js.

Because process.env is accessible at the global scope, it is important to note that environment variables are accessible from anywhere in your Worker script, including third-party libraries that you may be using. This is consistent with Node.js behavior, but it is something to be aware of from a security and configuration management perspective. The Cloudflare Secrets Store can provide enhanced handling around secrets within Workers as an alternative to using environment variables.

Importable environment and waitUntil

When not using the nodejs_compat flag, we decided to go a step further and make it possible to import both the environment, and the waitUntil mechanism, as a module, rather than forcing users to always access it via the env and ctx arguments passed to the Worker function. This can make it easier to access the environment in a more modular way, and can help to avoid passing the env argument through multiple layers of function calls. This is not a Node.js-compatibility feature, but we believe it is a useful addition to the Workers environment:

import { env, waitUntil } from 'cloudflare:workers';

const config = env.MY_ENVIRONMENT_VARIABLE;

export default {
  async fetch(request) {
    // You can still access env here if you need to
    const configFromEnv = env.MY_ENVIRONMENT_VARIABLE;
    // ...
  }
}

function doSomething() {
  // Bindings and waitUntil can now be accessed without
  // passing the env and ctx through every function call.
  waitUntil(env.RPC.doSomethingRemote());
}

One important note about process.env: changes to environment variables via process.env will not be reflected in the env argument passed to the Worker function, and vice versa. The process.env is populated at the start of the Worker execution and is not updated dynamically. This is consistent with Node.js behavior, where changes to process.env do not affect the actual environment variables of the running process. We did this to minimize the risk that a third-party library, originally meant to run in Node.js, could inadvertently modify the environment assumed by the rest of the Worker code.

Stdin, stdout, stderr

Workers do not have a traditional standard input/output/error streams like a Node.js process does. However, we have implemented process.stdin, process.stdout, and process.stderr as stream-like objects that can be used similarly. These streams are not connected to any actual process stdin and stdout, but they can be used to capture output that is written to the logs captured by the Worker in the same way as console.log and friends, just like them, they will show up in Workers Logs.

The process.stdout and process.stderr are Node.js writable streams:

import process from 'node:process';

export default {
  async fetch(request) {
    process.stdout.write('This will appear in the Worker logs\n');
    process.stderr.write('This will also appear in the Worker logs\n');
    return new Response('Hello, world!');
  }
}

Support for stdin, stdout, and stderr is also integrated with the virtual file system, allowing you to write to the standard file descriptors 0, 1, and 2 (representing stdin, stdout, and stderr respectively) using the node:fs APIs:

import fs from 'node:fs';
import process from 'node:process';

export default {
  async fetch(request) {
    // Write to stdout
    fs.writeSync(process.stdout.fd, 'Hello, stdout!\n');
    // Write to stderr
    fs.writeSync(process.stderr.fd, 'Hello, stderr!\n');

    return new Response('Check the logs for stdout and stderr output!');
  }
}

Other process APIs

We cannot cover every node:process API in detail here, but here are some of the other notable APIs that we have implemented:

  • process.nextTick(fn): Schedules a callback to be invoked after the current execution context completes. Our implementation uses the same microtask queue as promises so that it behaves exactly the same as queueMicrotask(fn).

  • process.cwd() and process.chdir(): Get and change the current virtual working directory. The current working directory is initialized to /bundle when the Worker starts, and every request has its own isolated view of the current working directory. Changing the working directory in one request does not affect the working directory in other requests.

  • process.exit(): Immediately terminates the current Worker request execution. This is unlike Node.js where process.exit() terminates the entire process. In Workers, calling process.exit() will stop execution of the current request and return an error response to the client.

Compression with node:zlib

The node:zlib module provides APIs for compressing and decompressing data using various algorithms such as gzip, deflate, and brotli. We have implemented the node:zlib module, allowing you to use familiar compression APIs in your Workers applications. This enables a wide range of use cases, including data compression for network transmission, response optimization, and archive handling.

import zlib from 'node:zlib';

export default {
  async fetch(request) {
    const input = 'Hello, world! Hello, world! Hello, world!';
    const compressed = zlib.gzipSync(input);
    const decompressed = zlib.gunzipSync(compressed).toString('utf-8');

    return new Response(`Decompressed data: ${decompressed}`);
  }
}

While Workers has had built-in support for gzip and deflate compression via the Web Platform Standard Compression API, the node:zlib module support brings additional support for the Brotli compression algorithm, as well as a more familiar API for Node.js developers.

Timing & scheduling

Node.js provides a set of timing and scheduling APIs via the node:timers module. We have implemented these in the runtime as well.

import timers from 'node:timers';

export default {
  async fetch(request) {
    timers.setInterval(() => {
      console.log('This will log every half-second');
    }, 500);

    timers.setImmediate(() => {
      console.log('This will log immediately after the current event loop');
    });

    return new Promise((resolve) => {
      timers.setTimeout(() => {
        resolve(new Response('Hello after 1 second!'));
      }, 1000);
    });
  }
}

The Node.js implementations of the timers APIs are very similar to the standard Web Platform with one key difference: the Node.js timers APIs return Timeout objects that can be used to manage the timers after they have been created. We have implemented the Timeout class in Workers to provide this functionality, allowing you to clear or re-fire timers as needed.

Console

The node:console module provides a set of console logging APIs that are similar to the standard console global, but with some additional features. We have implemented the node:console module as a thin wrapper around the existing globalThis.console that is already available in Workers.

How to enable the Node.js compatibility features

To enable the Node.js compatibility features as a whole within your Workers, you can set the nodejs_compat compatibility flag in your wrangler.jsonc or wrangler.toml configuration file. If you are not using Wrangler, you can also set the flag via the Cloudflare dashboard or API:

{
  "name": "my-worker",
  "main": "src/index.js",
  "compatibility_date": "2025-09-21",
  "compatibility_flags": [
    // Get everything Node.js compatibility related
    "nodejs_compat",
  ]
}

The compatibility date here is key! Update that to the most current date, and you’ll always be able to take advantage of the latest and greatest features.

The nodejs_compat flag is an umbrella flag that enables all the Node.js compatibility features at once. This is the recommended way to enable Node.js compatibility, as it ensures that all features are available and work together seamlessly. However, if you prefer, you can also enable or disable some features individually via their own compatibility flags:

Module Enable Flag (default) Disable Flag
node:console enable_nodejs_console_module disable_nodejs_console_module
node:fs enable_nodejs_fs_module disable_nodejs_fs_module
node:http (client) enable_nodejs_http_modules disable_nodejs_http_modules
node:http (server) enable_nodejs_http_server_modules disable_nodejs_http_server_modules
node:os enable_nodejs_os_module disable_nodejs_os_module
node:process enable_nodejs_process_v2
node:zlib nodejs_zlib no_nodejs_zlib
process.env nodejs_compat_populate_process_env nodejs_compat_do_not_populate_process_env

By separating these features, you can have more granular control over which Node.js APIs are available in your Workers. At first, we had started rolling out these features under the one nodejs_compat flag, but we quickly realized that some users perform feature detection based on the presence of certain modules and APIs and that by enabling everything all at once we were risking breaking some existing Workers. Users who are checking for the existence of these APIs manually can ensure new changes don’t break their workers by opting out of specific APIs:

{
  "name": "my-worker",
  "main": "src/index.js",
  "compatibility_date": "2025-09-15",
  "compatibility_flags": [
    // Get everything Node.js compatibility related
    "nodejs_compat",
    // But disable the `node:zlib` module if necessary
    "no_nodejs_zlib",
  ]
}

But, to keep things simple, we recommend starting with the nodejs_compat flag, which will enable everything. You can always disable individual features later if needed. There is no performance penalty to having the additional features enabled.

Handling end-of-life’d APIs

One important difference between Node.js and Workers is that Node.js has a defined long term support (LTS) schedule that allows it to make breaking changes at certain points in time. More specifically, Node.js can remove APIs and features when they reach end-of-life (EOL). On Workers, however, we have a rule that once a Worker is deployed, it will continue to run as-is indefinitely, without any breaking changes as long as the compatibility date does not change. This means that we cannot simply remove APIs when they reach EOL in Node.js, since this would break existing Workers. To address this, we have introduced a new set of compatibility flags that allow users to specify that they do not want the nodejs_compat features to include end-of-life APIs. These flags are based on the Node.js major version in which the APIs were removed:

The remove_nodejs_compat_eol flag will remove all APIs that have reached EOL up to your current compatibility date:

{
  "name": "my-worker",
  "main": "src/index.js",
  "compatibility_date": "2025-09-15",
  "compatibility_flags": [
    // Get everything Node.js compatibility related
    "nodejs_compat",
    // Remove Node.js APIs that have reached EOL up to your
    // current compatibility date
    "remove_nodejs_compat_eol",
  ]
}
  • The remove_nodejs_compat_eol_v22 flag will remove all APIs that reached EOL in Node.js v22. When using removenodejs_compat_eol, this flag will be automatically enabled if your compatibility date is set to a date after Node.js v22’s EOL date (April 30, 2027).

  • The remove_nodejs_compat_eol_v23 flag will remove all APIs that reached EOL in Node.js v23. When using removenodejs_compat_eol, this flag will be automatically enabled if your compatibility date is set to a date after Node.js v24’s EOL date (April 30, 2028).

  • The remove_nodejs_compat_eol_v24 flag will remove all APIs that reached EOL in Node.js v24. When using removenodejs_compat_eol, this flag will be automatically enabled if your compatibility date is set to a date after Node.js v24’s EOL date (April 30, 2028).

If you look at the date for remove_nodejs_compat_eol_v23 you’ll notice that it is the same as the date for remove_nodejs_compat_eol_v24. That is not a typo! Node.js v23 is not an LTS release, and as such it has a very short support window. It was released in October 2023 and reached EOL in May 2024. Accordingly, we have decided to group the end-of-life handling of non-LTS releases into the next LTS release. This means that when you set your compatibility date to a date after the EOL date for Node.js v24, you will also be opting out of the APIs that reached EOL in Node.js v23. Importantly, these flags will not be automatically enabled until your compatibility date is set to a date after the relevant Node.js version’s EOL date, ensuring that existing Workers will have plenty of time to migrate before any APIs are removed, or can choose to just simply keep using the older APIs indefinitely by using the reverse compatibility flags like add_nodejs_compat_eol_v24.

Giving back

One other important bit of work that we have been doing is expanding Cloudflare’s investment back into the Node.js ecosystem as a whole. There are now five members of the Workers runtime team (plus one summer intern) that are actively contributing to the Node.js project on GitHub, two of which are members of Node.js’ Technical Steering Committee. While we have made a number of new feature contributions such as an implementation of the Web Platform Standard URLPattern API and improved implementation of crypto operations, our primary focus has been on improving the ability for other runtimes to interoperate and be compatible with Node.js, fixing critical bugs, and improving performance. As we continue to grow our efforts around Node.js compatibility we will also grow our contributions back to the project and ecosystem as a whole.

Aaron Snell 2025 Summer Intern, Cloudflare Containers
Node.js Web Infrastructure Team
flakey5
Dario Piotrowicz Senior System Engineer
Node.js Collaborator
dario-piotrowicz
Guy Bedford Principal Systems Engineer
Node.js Collaborator
guybedford
James Snell Principal Systems Engineer
Node.js TSC
jasnell
Nicholas Paun Systems Engineer
Node.js Contributor
npaun
Yagiz Nizipli Principal Systems Engineer
Node.js TSC
anonrig

Cloudflare is also proud to continue supporting critical infrastructure for the Node.js project through its ongoing strategic partnership with the OpenJS Foundation, providing free access to the project to services such as Workers, R2, DNS, and more.

Give it a try!

Our vision for Node.js compatibility in Workers is not just about implementing individual APIs, but about creating a comprehensive platform that allows developers to run existing Node.js code seamlessly in the Workers environment. This involves not only implementing the APIs themselves, but also ensuring that they work together harmoniously, and that they integrate well with the unique aspects of the Workers platform.

In some cases, such as with node:fs and node:crypto, we have had to implement entirely new capabilities that were not previously available in Workers and did so at the native runtime level. This allows us to tailor the implementations to the unique aspects of the Workers environment and ensure both performance and security.

And we’re not done yet. We are continuing to work on implementing additional Node.js APIs, as well as improving the performance and compatibility of the existing implementations. We are also actively engaging with the community to understand their needs and priorities, and to gather feedback on our implementations. If there are specific Node.js APIs or npm packages that you would like to see supported in Workers, please let us know! If there are any issues or bugs you encounter, please report them on our GitHub repository. While we might not be able to implement every single Node.js API, nor match Node.js’ behavior exactly in every case, we are committed to providing a robust and comprehensive Node.js compatibility layer that meets the needs of the community.

All the Node.js compatibility features described in this post are available now. To get started, simply enable the nodejs_compat compatibility flag in your wrangler.toml or wrangler.jsonc file, or via the Cloudflare dashboard or API. You can then start using the Node.js APIs in your Workers applications right away.

Malicious-Looking URL Creation Service

Post Syndicated from Bruce Schneier original https://www.schneier.com/blog/archives/2025/09/malicious-looking-url-creation-service.html

This site turns your URL into something sketchy-looking.

For example, www.schneier.com becomes
https://cheap-bitcoin.online/firewall-snatcher/cipher-injector/phishing_sniffer_tool.html?form=inject&host=spoof&id=bb1bc121¶meter=inject&payload=%28function%28%29%7B+return+%27+hi+%27.trim%28%29%3B+%7D%29%28%29%3B&port=spoof.

Found on Boing Boing.

Свободата на словото като палачинка

Post Syndicated from Светла Енчева original https://www.toest.bg/svobodata-na-slovoto-kato-palachinka/

Свободата на словото като палачинка

Има понятия, които мнозина биха поставили на челно място в ценностната си система, но влагат в тях различно съдържание. Да вземем свободата. Ето няколко коренно различни вида свобода: на българското националноосвободително движение от 70-те години на XIX век, на сексуалната революция от 60-те години на ХХ век, на независимата от държавата икономическа инициатива, на будистите, стремящи се към свобода от егото си и присъщите му емоции.

Свободата на словото (и по-общо – на изразяването) е също толкова хлъзгаво понятие. Тя не само може да носи различно съдържание в зависимост от ценностите на адептите си, а и разбирането на границите ѝ може да варира спрямо разнообразни фактори, един от които – отношението към властта.

Доскорошните представи за свобода на словото

До неотдавна клишето гласеше, че в САЩ свободата на словото е пълна, защото е гарантирана от Първата поправка на американската Конституция, докато в Европа съществуват повече регулации – защита на личния живот, недопускане на омраза и пр. И действително, зад океана обидите, включително към публични личности, както и изразяването на омраза към цели социални групи оставаха като цяло без последствия.

Тази форма на свобода на словото се защитаваше като върховна ценност най-вече от дясно настроени американци. Но и от неамериканци, повлияни от идеала за „свободната Америка“ – в България например този светоглед се радва на широка популярност, не на последно място защото след 1989 г. на САЩ по нашите ширини се гледаше като на образец за свободния свят.

Затова едва ли не в мръсна дума се превърна т.нар. политическа коректност, тоест опитите да се въведе език, който да включва всички членове на обществото и да не е обиден или неприемащ за отделни групи. Дори за хора, които се идентифицират като либерални, стана непонятно и неприемливо използването например на определени местоимения, които да включват и транс хората, или избягването на думи като „негър“ и „циганин“.

Ако надзърнем обаче зад клишето,

ще се разкрие доста по-различна картинка. Американската представа за свобода на словото и на изразяването не поставя под въпрос определени табута върху неща, които в Европа се смятат за приемливи.

Когато американци дойдат в европейска страна, едно от първите неща, които ги изумява, е как хората свободно си пият алкохол на открито. В повечето градове в САЩ човек и бира да си е купил, да не говорим за уиски, трябва да крие бутилката в непрозрачен плик, ако е навън, да не би случайно някоя крехка детска душа да я види и да се поквари.

В Европа също така има доста по-голяма свобода по отношение на включването на сексуално съдържание и голота в изкуството и медиите в сравнение със САЩ. В много европейски страни е съвсем в реда на нещата открито да се продават списания, на чиито корици има хора с оскъдно или никакво облекло. Много филми и сериали, които в Щатите са забранени за лица под 18-годишна възраст, в Европа имат по-либерално ограничение – например 16+.

За разлика от САЩ, в Европа не е и толкова безвъпросно слагането на знак на равенство между голота и секс. В германските сауни например не е прието човек да влиза облечен и се предполага, че там хората, макар и дибидюс, нямат сексуален интерес един към друг. Не че и отвъд океана няма адепти на голотата, но те са доста по-нишови и субкултурни.

На 180 градуса

Едно от основните предизборни обещания на Тръмп и на кръга около него беше възстановяването на свободата на словото. Вече нищо не трябваше да бъде пречка пред нея – нито политическата коректност, нито правилата на социалните мрежи, нито институциите. Изобщо – пълна свобода.

Още преди официалното встъпване на Тръмп в длъжност започна да става ясно, че предстои обрат, а с течение на времето този обрат придобива невиждани размери за държава, смятана за демократична. Ето само няколко повея от вятъра на промяната:

И „словото на омразата“ се върна на бял кон.

Довчера отричано от републиканците, понятието „слово на омразата“ вече си е напълно легитимно и не се възприема като недопустимо посегателство срещу свободата на изразяване. То преживя направо апогей след убийството на консервативния лидер Чарли Кърк – всяка критика на възгледите му или дори само споменаването, че Кърк е отстоявал правото да носиш оръжие даже с цената на човешки жертви, се заклеймява като реч на омразата, заслужаваща най-строга санкция.

Вицепрезидентът Джей Ди Ванс например призова американците да донасят на шефовете си, ако техни колеги се радват на смъртта на Кърк. А за конгресмена републиканец Клей Хигинс доживотното отнемане на достъп до всички социални мрежи на авторите на „всеки пост или коментар, който омаловажава убийството на Чарли Кърк“ дори не е достатъчно наказание. Той настоява бизнесите им да бъдат включени в черни списъци, да бъдат изгонени от училища и университети и дори да се отнемат шофьорските им книжки. С две думи, осъжда „провинилите се“ на гражданска смърт.

Казусът с Джими Кимъл

Насред призивите за разправа с всеки злорадстващ за смъртта на Чарли Кърк, вечерното шоу на известния комик Джими Кимъл беше спряно и след няколко дни възстановено. Официалният аргумент за спирането на шоуто е именно неподходящият коментар на водещия за убития Кърк.

Колкото и да търсите обаче с какви думи Кимъл е обиждал Кърк, едва ли ще намерите, защото такива просто няма. „Скандалната“ му реплика дори не е за самата жертва, а за последователите на Тръмп, които

отчаяно се опитват да характеризират хлапето, убило Чарли Кърк, като нещо различно от себе си и правят всичко по силите си, за да натрупат политически точки от това.

Коментарът на Кимъл изобщо не е по-остър от реакциите на други комици, журналисти и публични личности с демократични убеждения. Нито по-смел. Скоро след излъчването му обаче председателят на Федералната комисия по далекосъобщенията Брендън Кар, приближен на Тръмп, заяви, че шоуто трябва да бъде спряно, добавяйки:

Можем да го направим по лесния или по трудния начин.

„Дисни“, собственици на телевизия ABC, в която е предаването на Кимъл, избират лесния начин. Защото Кар може и да няма право да нарежда кое шоу да бъде свалено, но от комисията му зависят медийни придобивания и сливания, каквито „Дисни“ извършва. След вълната от протести и спрени абонаменти компанията връща Кимъл, понеже щетите от „канселирането“ му току-виж се оказали по-големи от рисковете, ако остане в ефир.

Каква е истинската причина за спирането на Кимъл, припомня друг „канселиран“ комик – Стивън Колбер. Макар той да е лицето на вечерното шоу с най-висок рейтинг в САЩ, то няма да бъде подновено след май 2026 г. Официалният аргумент е поради финансови загуби, а по-вероятният – водещият не се харесва на Тръмп. По повод на Кимъл Колбер казва:

„Така че, каквото и да твърдят, не става дума изцяло за това какво Джими е казал в понеделник, а за част от план. Откъде знам ли? Преди два месеца, когато президентът изискано празнуваше спирането на шоуто ми, той постна: „Джими Кимъл е следващият, който ще си ходи.“

Кимъл е трън в очите на Тръмп от години. Ясно е било, че в шоуто си водещият ще коментира нещо по повод смъртта на Чарли Кърк. И е било все едно какво точно ще каже – просто се е търсел повод да бъде отстранен. И ако първият опит беше неуспешен, това не означава, че няма да има следващ. Тръмп вече заплаши ABC заради решението на телевизията да върне комика.

Свободата на словото като палачинка

Двойните стандарти за свободата на словото и речта на омразата

Републиканците, които разчистват сметки с политическите си противници, претендирайки, че се борят с речта на омразата, много бързо са забравили какви са ги приказвали самите те, преди Тръмп да си върне властта. CNN припомня, че само преди година същият Брендън Кар, според когото Джими Кимъл трябва да бъде отстранен „по лесния или по трудния начин“, е нарекъл свободата на словото противотежест на демокрацията, която ограничава правителствения контрол, а цензурата – мечтата на авторитарния лидер.

В същото предаване на CNN, както и в The Daily Show, водено от друг неудобен за властта комик – Джон Стюарт, се споменават редица случаи, когато последователи на Тръмп (а понякога и самият той) изразяват омраза, подиграват се с жертви на престъпления и призовават към насилие, но думите им остават без последствия.

Водещият на Fox Джеси Уотърс например разпространява конспиративната теория, че имунологът Антъни Фаучи е виновен за разпространението на COVID-19 в САЩ, и предлага Фаучи да бъде застрелян от засада. В резултат Фаучи получава смъртни заплахи, дъщерите му са тормозени, но Уотърс не е наказан.

През 2022 г. Пол Пелоси, съпруг на тогавашната председателка на Долната камара на Конгреса Нанси Пелоси, е нападнат с чук. Това отприщва вълна от подигравки в лагера на Тръмп, въпреки че 82-годишният Пелоси получава фрактура на черепа и претърпява операция. Тогавашният водещ на Fox Пийт Хегсет се смее в ефир на коментар на друга водеща в медията, че Пелоси може би е имал нужда от чук. „Имаше последици – този джентълмен трябваше да напусне телевизията“, каза Джон Стюърт, иронизирайки факта, че днес Хегсет е министър на отбраната на САЩ.

Доналд Тръмп-младши пък поства снимка на чук върху долни гащи с думите: „Костюмът ми на Пол Пелоси за Хелоуин е готов“. Самият Доналд Тръмп пък заяви: „Ще се изправим срещу лудата Нанси Пелоси, която съсипа Сан Франциско“, и ехидно се обърна към нея: „Как е съпругът ти, между другото?“

Ценностна хигиена

По времето на втория мандат на Тръмп властта се обръща срещу свободата на словото по безпрецедентен за САЩ начин. Досега не е било човек да не смее да отиде на екскурзия в Америка, защото е писал нещо във Facebook. Този обрат неизбежно оказва влияние и на други места по света, включително в Европа, не само заради инструментите за натиск, с които САЩ разполагат, а и защото съвсем доскоро бяха символ на свободния свят.

В по-малка степен обаче такива обрати не са прецедент и случващото се отвъд океана е подходящ повод да се вгледаме в собствената си градинка. Защото и тук мнозина се кълнат в свободата на словото. Но всеки, който казва, че тя е абсолютна, все пак слага границата някъде. Дали например един разследващ журналист ще одобри, ако някой публикува личните му данни – адрес, телефон, ЕГН, номера на банкови карти – и всеки, който му има зъб, може да ги използва, както намери за добре? Дали един борец срещу цензурата ще се радва, ако изтекат сексуални компромати с негово участие?

Джон Стюарт дава пример с хора от най-близкото обкръжение на Тръмп, които заявяват, че е недопустимо да наричаш опонентите си фашисти, врагове на държавата и да ги дехуманизираш. В същото време самият Тръмп прави и трите неща. Но той може, а демократите – не. По подобен начин и у нас се практикуват двойни стандарти: едно и също нещо може да се интерпретира като проява на кураж и като слово на омразата – зависи кой и на кого го казва.

Всичко това не означава, че свободата на словото не бива да бъде отстоявана. Напротив. Но тя е лишена от съдържание, ако не се определят ясно и честно границите ѝ, както и ценностите, които стоят зад нея.

В противен случай рискуваме да станем абсурдни като онези борци против цензурата, които реторично питат: „Аз как ще обясня на децата си…?“ и за които свободата на словото се свежда до изразяване на омраза. И – парадоксално – до стремеж към налагане на цензура. 

Да покажа човешката крехкост

Post Syndicated from Стефан Иванов original https://www.toest.bg/da-pokazha-choveshkata-krehkost/

С Алиса Коваленко разговаря Стефан Иванов

Да покажа човешката крехкост

Алиса Коваленко е украинска документална режисьорка, родена през 1987 г. в Запорожие. Учила е кинодокументалистика в Киевския университет, а по-късно и във Варшава. В нейните филми често се разглеждат последиците от руската агресия от анексията на Крим през 2014-та до войната, започнала осем години по-късно. Сред по-известните ѝ творби са Alisa in Warland (2015), Home Games (2018) и We Will Not Fade Away (2023) – филми, които съчетават личната перспектива и документалното изследване на войната и травмите от нея. През 2022 г. тя се присъединява към Украинската доброволческа армия, а след това довършва We Will Not Fade Away и започва работа върху „Скъпи мой Теo“ – видеодневник, посветен на нейния син. Алиса е и активистка чрез филмите си, но и чрез личната си история и ангажимент, особено по темата за сексуалното насилие по време на война.

Най-новият ѝ филм „Скъпи мой Теo“ (My Dear Théo), интимна творба под формата на писма от фронта до нейния син, показва войната през личната призма. Прожекцията ще се състои в рамките на фестивала Sofia DocuMENTAL ’25 на 2 октомври, 19:00 ч., в Дома на киното и ще бъде последвана от среща с екипа.

„Скъпи мой Теo“ е структуриран като писма до сина Ви. Как писането и снимането в тази форма Ви помогнаха да преработите реалността на войната?

Този филм не беше замислен като филм от самото начало. От първите дни на фронта не се чувствах като режисьор, киното сякаш беше загубило всякакво значение. Камерата ми прекарваше времето в раницата ми, в окопи и траншеи. Снимах спонтанно малки фрагменти от живота. По-скоро имах чувството, че създавам видеоалбум за спомен.

С писмата беше различно – те ми помогнаха да осмисля реалността на войната. Те бяха за моя вътрешен свят, чувства, мисли, емоции, нещо екзистенциално, което камерата не може да улови. И вероятно имаше нещо терапевтично в това. Когато изразиш реалността около теб с думи, това ти помага да я разбереш по-добре. Но най-дълбокото осъзнаване дойде на етапа на монтажа.

Като майка и войник Вие изпълнявате две различни роли – как те съжителстват във Вас и как са повлияли на тона на филма?

Съжителството на двете роли – на майка и на войник – ми носи както огромна болка, така и невероятна сила. По време на силен обстрел, когато мислех за смъртта, осъзнах, че ако умра, умирам два пъти. Умирам и за сина си. И това, което мога да дам на детето си, цялата любов, също умира. Това е ужасно осъзнаване, но ми даде сила, защото исках да оцелея, за да може любовта да продължи.

Войната те прави по-твърд, изсмуква част от нежността ти. Майчинството беше балансиращ фактор за мен. Всички писма и филмът бяха опит да съчетая идентичностите на войник и майка. Истинската идея дойде от размислите ми за преходността на паметта – как можем да я съхраним за нашите деца, особено след като загинаха мои близки братя по оръжие, които също бяха родители.

Филмът Ви улавя тишината между атаките и нежността между войниците. Защо беше важно за Вас да подчертаете тези по-тихи моменти, а не само насилието?

Всъщност животът на фронта е по-скоро чакане, отколкото действие, и често може да бъде адски скучен. Има известно изкривяване на реалността в социалните медии и в новините, където постоянно виждаме изображения на събития и битки. Разбира се, никой няма да гледа новини за група войници, които чакат нещо в окоп в гората. И въпреки че може да умреш, докато чакаш, това не изглежда привлекателно или драматично нито за киното, нито за медийния свят. Важно е да се разбере, че действието не може да продължи интензивно толкова дълго време. Все пак го правиш на скокове, граничещи с очакване. Напредваш, после чакаш. Винаги чакаш. И тишината също е от съществено значение в средата на всичко това, тя е специална категория – всеки войник знае, че тишината може да бъде по-заплашителна от експлозиите.

Исках да говоря за невидимата страна, за рутинната работа, да разширя представата, възприятието за реалността на фронтовата линия. За мен войната е рутина, тя е тежка, дълга, изтощителна работа, която се повтаря отново и отново и не прилича на героична битка, а и не всяка смърт е героична. Пристигаш, ядеш малко консервирано месо, гледаш листата през термовизионна камера в продължение на няколко дни, мина излита над главата ти и умираш. Но има и друго измерение на тези видения – всички тези мисли, спомени и чувства, които те пронизват – това е съвсем друга емоционална, екзистенциална вселена. Исках да се опитам да уловя и да слея тези две измерения на фронтовата линия.

Много военни филми акцентират върху героизма. Вие обаче сте избрала интимността и уязвимостта. Какво Ви насочи към тази перспектива?

Мисля, че истинският героизъм започва с вътрешна човешка чувствителност. И именно чрез нея можем да се разбираме по-добре, да изпитваме съпричастност, приятелство, любов. За мен беше важно да не говоря за някаква абстрактна категория военни или героични воини, а за моите близки, да разкрия лицата ни зад каските, да покажа, че зад тях стоят обикновени хора, които обичат, мечтаят, страхуват се, да покажа човешката крехкост.

И чрез универсалната човешка природа да покажа, че на фронта сме всички ние, цялото сечение на обществото ни, хора от всички професии – артисти, обикновени работници, инженери, ИТ специалисти, както и бащи, синове, дъщери, братя, сестри, майки.

Ние не бяхме смели войници през цялото време, повечето от нас не бяха военни преди руската агресия и не искаха да бъдат такива. Трябваше да го направим, за да защитим дома си, семейството си. И като цяло трябва да бъдем предпазливи с героизма, защото той често може да изтрие истинските черти от лицата на хората.

Кой беше най-трудният момент за снимане – не от техническа, а от емоционална гледна точка – и как решихте да го оставите в окончателния монтаж?

Началото беше най-трудното. Дори преди началото. Току-що бях започнала да гледам заснетия материал, за да имам представа какъв е, и тогава мой близък загина, а скоро след това и друг. Не можех да се справя. Гледах минута, после отивах да плача десет минути и това продължи дълго. Тези материали чакаха година, а аз се страхувах да ги докосна. Дори престанах да вярвам, че ще излезе нещо от това, мислех, че може би трябва да го оставя за след време.

Когато дойдох на първата ни сесия за монтаж във френския град Монсегюр и след първите дни, в които гледахме заедно заснетия материал, почувствах, че не мога да работя по монтажа. Това бяха лицата на моите починали скъпи приятели, които ми бяха близки, и когато мисля за тяхната смърт, ме обзема неописуема болка. Осъзнах, че ако не намеря някакъв метод, някакъв изход от тези емоции, ще полудея. Нервно си мислех, че трябва спешно да измисля някакъв трик. И най-накрая успях. Изведнъж осъзнах, че не става въпрос за болката, а за възможността да се запази този живот, този спомен. Преодолях отчаянието с чувството, че създаваме капсула на времето, в която можеш да дойдеш, когато пожелаеш, и да ни видиш всички живи.

Да пишеш на сина си по време на война е нещо дълбоко лично и в същото време универсално. Представяла ли сте си други майки, деца или бъдещи поколения като част от аудиторията си?

Когато пишех писмата, не можех да си представя никой друг освен сина си. По-късно това започна да се разкрива като нещо универсално, общ глас, мост на спомените, почит към родителите, които са дали живота си за бъдещето на децата си. Че всъщност това е нещо повече от личната ми история и че може да бъде ценно за хора с подобни преживявания, за тези, които са загубили близки, за бъдещите поколения.

Преди да завърша монтажа, показах почти окончателния вариант на един важен и специален човек, колежка и приятелка – Олга Бирзул. Нейният съпруг Виктор Ониско, който беше известен филмов монтажист в Украйна, загина на фронта в края на 2022 г. След като гледа филма, тя ми написа: „Благодаря ти. Чаках точно такъв филм.“ И това беше най-ценната обратна връзка за мен.

Размишлявах и за по-младото поколение, което идва, и се замислих какво можем да им дадем, как трябва да говорим с тях, как можем да се разберем. По време на една от прожекциите, в рамките на сесията с въпроси и отговори, един от моите бойни другари каза нещо, което беше значимо за мен: това не е филм за нашето минало – това е филм, който ни служи като пътеводител за нашето бъдеще, показвайки ни цената, която сме платили за свободата, и как трябва да се погрижим да не бъде пропиляна.

Как войната промени представата Ви за това какво може или трябва да прави киното? Вие сте войник, но и артист. Смятате ли, че изкуството може да бъде форма на съпротива?

В началото на пълномащабната война напълно загубих вярата си в киното и неговата роля в съпротивата. Срещнах тази война във влака, когато пътувах към последната сесия за заснемане на предишния ми документален филм за тийнейджъри от селата на фронтовата линия в Донбас – We Will Not Fade Away. Прекарах първите няколко дни със семейството на един от героите ми в село на няколко километра от фронтовата линия, където всички очакваха руснаците да превземат селото всеки момент. Бях объркана. Снимах някак механично, но в сърцето си бях загубила напълно всякакво чувство за смисъл в това занимание. Какво можеш да направиш с камерата си, когато ракети падат върху твоите близки, семейството ти, приятелите ти, героите в незавършения ти филм? Изглежда абсурдно.

След фронта не беше лесно да възвърна вътрешната си вяра в киното. И вероятно никога не успях да я възвърна напълно, не можах да се върна и към себе си. Но трябваше да завърша филма и всички разбирахме, че е необходимо да говорим за Украйна, че гласовете ни трябва да бъдат чути.

Рационално разбирам, че културата и киното са важни, разбира се, те са кодекс на човешките ценности и чувства, но все още ме измъчват този вътрешен конфликт и фактът, че трябва да се върна на фронта, защото там сега е основната ни линия на отбрана. Но културата също е едно от онези ценни неща, които трябва да защитаваме. Това е като концепцията за отрицателна и положителна свобода: трябва да знаеш срещу какво се бориш, но и за какво се бориш.

Развих ясно отхвърляне на концепцията за „изкуството за изкуството“. Или ме дразни, когато чуя нещо като „културата извън политиката“. Не мисля, че някога ще мога да приема такова кино. Вероятно киното, поне документалното, е станало за мен равностойно на човешкото действие и на отговорността за него – в по-голяма степен, отколкото преди.

Филмът е антивоенен, но е създаден в резултат на войната. Как съчетавате този парадокс в работата си и в живота си?

В момента живеем в пълен парадокс. И макар да е наистина изтощително да съществуваме в тези парадокси, изглежда, че именно те ни позволяват да открием някои дълбоки екзистенциални значения.

Веднъж разговаряхме с колега за погрешното схващане, че птиците не пеят, когато експлодират снаряди, но те пеят и дори пеят като луди. Когато работехме върху звука за филма, слушахме тези невероятни трели в моите оригинални видеозаписи от фронтовата линия по време на ужасни обстрели. Това е парадокс: сред смъртта и разрухата природата се стреми да продължи живота. Отиваме на работа след обстрела, шегуваме се, раждаме деца, пишем книги, правим филми по някакъв начин – като тези птици. Научаваме се да живеем и да балансираме между бездната и болката, да не губим сетивата си, да не губим чувствителността си, моментите на малко щастие, любовта, топлината вътре в нас.

Как искате синът Ви Тео да гледа този филм един ден?

Тео вече е гледал филма, дори може би пет пъти. Смятах, че е важно да го гледа преди световната премиера в Копенхаген, тъй като планирах да го заведа там с мен. Организирахме частна семейна прожекция в малко кино в Киев. Аз държах ръката му от едната страна, а баща му – от другата. Бях притеснена как ще реагира емоционално, защото филмът не беше за малкия Тео, а писмата във филма бяха за бъдещия по-голям Тео, така че не бях сигурна дали ще разбере напълно всичко екзистенциално. Но той го почувства. Реагираше на всичко, което се случваше, дори си спомняше моменти, когато му се обаждах от фронта. В един момент, докато гледаше фрагмент от нашия личен архив във филма, той ме погледна и каза: „Мамо, потъвам в носталгия.“ Един момент ме засегна особено силно. В една сцена във филма говоря за родителите, които отиват на фронта, за да не се налага децата ни да го правят. Тео се обърна към мен и каза:

Мамо, не искам да се връщаш на фронта. Аз ще отида вместо теб.

Надявам се да разбере по-ясно, че този филм е за светлината, човешката чувствителност, нежността, близостта, любовта, която остава в сърцето въпреки смъртта. И че именно любовта и светлината ни дават силата да устоим на мрака и да продължим борбата.

Да покажа човешката крехкост
Кадър от филма „Скъпи мой Теo“

Когато погледнете отвъд войната, какви истории се чувствате длъжна да разкажете след нея?

В момента завършвам нов документален филм – Traces, който разкрива свидетелствата на украински жени, оцелели от сексуално насилие и изтезания, причинени от руската агресия в Украйна. Планираме да завършим постпродукцията до края на годината. От 2019 г. съм и член на SEMA Ukraine – организация на жени, преживели сексуално насилие, защото и аз бях пленена и преживях насилие през 2014 г., когато отидох да снимам събитията в Донбас – тогава всъщност започна руската агресия.

В сърцето си искам да правя филми за деца. Започнах да мисля за важността на филмовото образование за деца. Нашият свят полудява и не изглежда, че ние, възрастните, ще успеем да го оправим, но е наша отговорност да дадем някакви стълбове, нещо, за което новото поколение да се държи и да устои на цялото това цунами от дезинформация, насилие, потъпкване на ценностите и популизъм. Да им дадем инструменти, с които да се защитят. Защото след нас те ще бъдат тези, които ще предпазят света от разруха. Ние трябва да дадем максималното, на което сме способни.

Teaching Experience AI: Lessons from educators in Mexico

Post Syndicated from Liz Eaton original https://www.raspberrypi.org/blog/teaching-experience-ai-lessons-from-educators-in-mexico/

In classrooms across Mexico, a transformation is unfolding. The Experience AI programme isn’t just teaching students about artificial intelligence, it’s empowering teachers and learners to explore, question, and create with it. By equipping educators with accessible tools and sparking curiosity among students, the initiative is shaping a new generation ready to use AI responsibly and creatively.

Teacher at the front of the classroom

Educators like Guadalupe Cortes, Lilia Violeta Garvia Sanchez, Ines Martinez, and Ana Judith Zavaleta are at the forefront of this shift. Their experiences reveal just how transformative Experience AI has become.

From fear to fascination: Demystifying AI

For many, AI can feel abstract, something from science fiction. Science and math teacher Lilia Violeta Garvia Sanchez remembers that both she and her students once viewed AI as “robots that would take over the world.” Fear gave way to fascination, however, once Experience AI entered the classroom.

Through hands-on lessons, students quickly discovered AI as a practical tool rather than a threat. “I’ve seen a change in the students,” Lilia explains. “They were afraid at first, but now they’re curious and engaged.”

Technology teacher Ines Martinez admits she was also surprised: “I thought the language would be more technical or complex, but it was pleasantly accessible — and very useful.”

Equipping educators with tools that work

A defining strength of Experience AI is its adaptability. Teachers can tailor materials to fit their classrooms while still leaning on the program’s robust foundation.

Guadalupe Cortes points to the built-in glossary as a game-changer: “It was really helpful for me.” She values being able to choose what fits her teaching to keep it relevant: “I selected certain parts to connect with projects I was already running.”

Sparking critical thinking and ethical awareness

Experience AI pushes students to think deeply about the ethics and implications of AI.

In Ines’s class, students raised concerns about water use in data centres and debated how to protect their digital identities. They weren’t just learning facts, they were making connections to real-world issues.

Educator supporting young learner in the classroom

Another teacher, Ileana Beurini, described an exercise where students asked different AI models the same political question. When answers varied, they discussed bias and the importance of consulting multiple sources. In another activity, searching images of “worker” led to a conversation about gender equity in technology.

As Ines puts it: “They don’t want it to do all the thinking for them. They said it should be a support — a tool to generate better information, not to replace reasoning or reflection.”

Transforming engagement and performance

The impact on student motivation has been striking. For Ana Judith Zavaleta, the shift was clear: “They’re much more hands-on now — they don’t rely as much on textbooks or theory.” One student who typically struggled academically became one of the most enthusiastic participants, even passing where he previously failed.

Guadalupe Cortes has seen similar enthusiasm: “They’re finding a real purpose in using AI for their own benefit.” At an entrepreneurship fair, her students applied AI concepts to improve their projects, proof that these lessons extend far beyond the classroom.

A call to action for educators

The teachers’ message is unanimous: embrace AI.

“We should give it a try,” urges Lilia. “Just because we’re teachers doesn’t mean we have to know everything. The world is evolving every single day, and we need to innovate with our students so they feel motivated to keep learning.”

Young learners work on the classroom wall

For Ines, the takeaway is simple but powerful: “Take the risk — really, take the chance to learn. Just like the internet became essential, AI will become part of our daily lives and necessary for all areas of teaching — and life itself.”

More than just a set of resources

Experience AI is more than a set of resources, it’s a movement preparing students to navigate the future with curiosity, critical thinking, and ethical awareness. By igniting minds in Mexico, it’s helping to cultivate responsible digital citizens who will shape not just their classrooms, but the world beyond them.

For more information about Experience AI, visit our website: rpf.io/experienceai

For more information about our global Experience AI partner in Mexico, visit: educacionparacompartir.org

The post Teaching Experience AI: Lessons from educators in Mexico appeared first on Raspberry Pi Foundation.

Времето е в нас и ние сме под времето

Post Syndicated from original https://www.toest.bg/vremieto-e-v-nas-i-nie-sme-pod-vremeto/

Времето е в нас и ние сме под времето

В началото на септември ми се наложи да отменя плановете си да отида до Созопол по здравословни причини. Не бях точно болна, но не бях и съвсем здрава, а докато информирах приятелите, с които вече се бях разбрала да се видим там, съжалих, че на български не съществува еквивалент на английския идиом under the weather, който буквално означава „под времето“, но се използва точно за такива случаи на „неразположение“. Освен пространствено неопределена – „(раз)положение“ спрямо какво? – думата и особено производното ѝ прилагателно „неразположен(а)“ звучат и старомодно евфемистично, сякаш са по-скоро от роман на Джейн Остин, отколкото от съвремието.

Английският израз under the weather също е пространствено озадачаващ – как точно човек се намира „под времето“? – и макар да звучи значително по-модерно, се оказва, че също датира от времето на Остин. Фразата всъщност започва да се използва идиоматично през първите няколко десетилетия на XIX век, често като описание на финансови затруднения, неспособност за справяне или повсеместно непрокопсване, понякога по отношение на цели институции, индустрии или градове. С течение на времето обаче словосъчетанието „под времето“ все пак се установява в английския като идиом, описващ индивидуално излизане от форма и с това значение продължава да се употребява и досега.

Теориите за точната първоначална семантика на израза са няколко, но според всички той е свързан с мореплаването, или по-точно с предизвикателствата на неблагоприятните метеорологични условия, пред които мореплавателите често са изправени. Според една от версиите за произхода на идиома той идва от практиката страдащите от морска болест¹ моряци да търсят спасение от лошото време, като се крият на завет под палубата. Един вид, времеубежище – само че не от хронологията на историята, а от атмосферните условия.

Ако оставим литературните неологизми настрана, идиомът under the weather, за съжаление, не съществува в българския език – нито в буквален превод, нито под формата на някакъв приблизителен еквивалент. Отсъствието му обаче е направо пренебрежимо в сравнение с една много по-съществена – и истински любопитна! – езикова липса.

За разлика от английския, където думата weather обозначава метеорологичния феномен, а time се използва за хронологичния, българският разполага само с едно наименование за двете понятия – това е именно думата „време“.

Неизненадващо, нашият език не е единственият, в който се наблюдава тази липса. Двете понятия се означават с една и съща дума (сходна на българската „време“, от старобългарската врѣмѧ²) и в останалите южнославянски езици, в унгарски (idő), както и в романските езици (temps във френски, tiempo в испански, tempo в италиански и португалски), в които думата произлиза от латинската tempus (а тя от своя страна също съдържа двете значения)³.

Изненадата, поне за мен, идва не толкова от несходствата между езиковите групи, а вътре в самите тях. Западно- и източнославянските езици например се разграничават от южнославянските си братовчеди и се присъединяват към английския и останалите германски (а и повечето световни) езици, където двете понятия се обозначават с две думи. В руски, украински и полски тези две думи са съвсем отделни – съответно „время“ и „погода“; „часи „погода“; czas и pogoda, – докато в чешки и словашки те са сходни, но все пак различни: čas и počasí(е).

Интересно изключение прави и румънският, чиято ситуация отразява както формалната му принадлежност към романското езиково семейство, така и практическата му свързаност с неговите балкански съседи. За разлика както от едните, така и от другите обаче, румънският си служи с две отделни наименования: за понятията, свързани с хронологичното време, и за времето като философско понятие се използва думата с латински корен timp, а за атмосферните условия – славянската думата vreme.

Оказва се, че разделението на езиците на географски принцип предлага доста по-чиста картина, отколкото принадлежността им към една или друга езикова група.

Ако си представим картата на Европа според държавите, които използват една обща дума за „време“, и тези, които използват две отделни, тя би била ясно разделена на южна и северна част.

Но и в това разделение също има любопитни изключения, сред които са латвийският (за разлика от заобикалящите го езици, тук думата е една – laiks) и албанският (тук пък са две – kohë и mot). Но най-фрапантното изключение идва от гръцкия, където за понятието „време“ съществуват не една, не две, а цели три отделни думи: χρόνος (khrónos) – времето като интервал между две събития, както и понятие, което изразява последователността и продължителността на явленията (носи и значението на „година“); καιρός (kaírios) – времето като метеорологично понятие, както и като период/отрязък от време или епоха; и ώρα (óra) – освен за „час“ също може да се използва за времето в смисъл на определена част от деня, подходящо за някакви конкретни дейности. (Последната дума служи и за корен на прилагателното ωραίο (oraío), тоест „хубаво“ или „красиво“, което обаче първоначално е значело „навременно“. Според някои теории оттам произлиза и наименованието на бисквитите Oreo.)

Времето е раздел(е)но и в турския език. Там думата за понятието, свързано с продължителност, епоха, или период, е zaman (навлязла в българския заедно с израза „зор заман“), докато тази, обозначаваща метеорологичното време, е hava, буквално „въздух“ (оттам и въпросът „Как е хавата?“).

Очакванията ми да открия някакво особено вълнуващо обяснение за различните подходи на различните езици се оказват неоправдани – лингвистите не предлагат такова и посочват „езикови инерции“ и „предвидими закономерности“: някои езици просто запазват старата полисемия (една дума с няколко значения) и разчитат на контекста, докато други развиват/заемат нова лексика и така отделните значения започват да се назовават с различни думи.

Със или без вълнуващи обяснения, двете понятия очевидно са концептуално свързани – течението на времето и смяната на сезоните неминуемо влияят на атмосферните условия. Същевременно заобикалящият ни свят (и атмосферните условия) несъмнено се отразява на езика, с който ги възприемаме и описваме. Както, струва ми се, е вярно и обратното: езикът със сигурност влияе на начините, по които възприемаме и описваме околния свят.

Ето защо предполагам, че макар и условно и отнасящо се само за Европа, разделението север/юг вероятно не е съвсем случайно. Може би много по-суровите и екстремни условия в северната част на континента изискват специфични думи, с които да бъдат назовани, докато сравнително мекият климат на Средиземноморието и Балканите няма нужда от отделни наименования?

В тази връзка се сещам за твърдението, че ескимосите разполагат с огромен брой – десетки, а даже и стотици – думи за различни видове сняг. Следвайки тази логика, се питам дали фактът, че в английския има отделна дума, с която се обозначават метеорологичните условия, поне донякъде обяснява пословичния афинитет на англичаните към обсъждането на времето. Тоест имат си думата weather – ползват си я.

Така или иначе, англичаните може и да са световни шампиони по обсъждане на времето, но далеч не са единствените първенци в тази дисциплина – според различни изследвания the weather е популярна тема за разговор и в САЩ, Канада, Ирландия, Австралия и Нова Зеландия – все места, където не само английският е официален език, а и климатът, особено в сравнение с южната част на Европа, е променлив, непредвидим и/или екстремен.

Обсъждането на времето (метеорологичното) е любим начин да се запълни времето (хронологичното) и да се разчупи ледът и в ледовитите – както пряко, така и преносно – скандинавски държави. В това се уверих лично неотдавна – това лято така и не стигнах до Созопол, но за сметка на това прекарах няколко дни в Стокхолм. Там научих, че шведският, подобно на английския и на останалите скандинавски езици, разполага с отделни думи за двете понятия, като väder (атмосферното време) е популярна тема за разговор.

Точно по време – а и благодарение – на един ветровит следобед в Стокхолм, докато слушах как едни хора обсъждат времето, ме осени съвсем неочаквано откритие. Българският може и да не разполага с отделна дума, която да обозначава метеорологичните условия, но шведската väder (както и нейните роднини в останалите германски езици) всъщност споделя общ произход – от праиндоевропейската *h₂weh₁- („вея“) – с българското наименование на едно от основните метеорологични явления, а именно с думата „вятър“!6 Етимологията, оказва се, хич не е вятър работа.7

Другата българска дума, която – още по-изненадващо! – споделя общ праиндоевропейски корен с прагерманската wedrą, откъдето произлизат английската weather, шведската väder, немската Wetter, исландската veður и т.н., е прилагателното „ведро“. Само че с ударение не на втората сричка, както във „вали като из ведро“8, а на първата – в смисъл „ясно, хубаво (време)“.

Използвам случая да премина от вятър на дъжд, и то не в метафорично-темпоралния, а в буквално-метеорологичния смисъл. Докато отменях плановете си за ходене до Созопол, въпреки че прогнозата беше за топло и слънчево време, се сетих за още един англоезичен идиом, който щеше добре да пасне на ситуацията – израза [to take a] rain check, тоест отлагането на план за някакъв неконкретизиран по-нататъшен момент. Тъкмо започвах да съжалявам, че на български, както и за under the weather, не съществува негов достоен еквивалент, когато една приятелка, в отговор на моето съобщение, че се налага да отложим уговорката, ми написа: „Не се притеснявай! Пишем го дъждовен!“

А когато (неуспешно) се опитах да върна неизползвания си билет за влака за Бургас, в ума ми изникна краткия, но красноречив български израз „след дъжд качулка“, който чудесно обединява в себе си както темпоралното, така и метеорологичното понятие за време. Този влак вече беше отпътувал. Или както се казва на изобилстващия от мореплавателска лексика английски, този кораб вече беше отплавал.

1 Етимологията на наименованията на морската болест и различните ѝ симптоми в различни езици сама по себе си е крайно любопитна. На български това „неразположение“ е известно и под общото понятие „кинетоза“ – от гръцката дума κίνησις (kínēsis ‘движение’), откъдето през немски в български навлиза и думата „кино“ в смисъл на „движещо се изображение“. На френски, освен с буквалното и благозвучно название mal de mer, морската болест се нарича и с термина naupathie – от гръцката дума ναῦς (naús ‘кораб’), която е и в корена на английското название на един от основните симптоми на болестта – nausea, тоест „гадене“.

2 Славянската дума „време“ няма общо с прагерманската *tīdiz, откъдето произлизат понятията, с които темпоралното време се нарича в съвременните германски езици (time, Zeit, tid и т.н.), но пък споделя изненадваща етимологична родственост с една друга дума в тях, а именно думата за „червей“: worm в английски и нидерландски, orm в норвежки и датски, Wurm в немски и т.н. Оказва се, че всички те произлизат от праиндоевропейския корен *wert- (‘въртя, завъртам, обръщам’). Wurm също така е част от една от любимите ми сложни думи в немския – Ohrwurm, буквално от Ohr (‘ухо’) + Wurm (‘червей’), за която се обзалагам, че ще я преживеете лично, след като прочетете последната бележка към този текст.

3 Самата дума „време“ може и да е със старобългарски корен, но в езика ни все пак са навлезли няколко думи, които произлизат от латинската tempus. Освен очевидните „темпо“ и „темпорално“ сред тях са също „температура“ и „темперамент“.

4 Гръцката дума καιρός (kaírios), която описва времето като метеорологично понятие, започва да се използва в този смисъл едва през византийския период. В старогръцкия вместо общо понятие са се използвали думи за конкретните атмосферни явления, например χειμών (cheimón ‘виелица’, ‘зима’) или αἰθήρ (aithḗr ‘ясно небе’), откъдето произлиза и българската думата „етер“, а промените в метеорологичните условия, разбира се, са били приписвани на боговете.

5 Според изследване, публикувано това лято, жителите на Великобритания прекарват средно около 57 часа (близо две денонощия и половина) годишно – или четири месеца и половина от целия си живот – в обсъждане на времето.

6 Думите за „вятър“ в германските езици (wind/vind), както и в романските езици (vent/vento/viento) произлизат от същия праиндоевропейски корен *h₂weh₁- (‘вея’) като българския им еквивалент. Интересно е, че в някои от германските и романските езици думите за „вятър“ от своя страна са корен в думите за „прозорец“ (например window в английски, vindu в норвежки и ventana в испански). Предположих, че това може да се отнася и за българската дума „витрина“, но се оказва, че тя води началото си – чрез френската vitrine, от латинската vitrum („стъкло“) – от праиндоевропейския корен *wed-, от който произлиза и думата *wódr (‘вода’).

7 Откриването на етимологичната връзка между английската дума weather и българската дума „вятър“ хвърля нова светлина и върху идиомa under the weather от началото на този текст. Според една от популярните теории за неговия произход той всъщност е скъсена версия на по-дългата фраза under the weather bow, като weather bow се използва за название на изложената на вятъра страна на кораба. На български тази страна се нарича „наветрена“. По някакво случайно езиково съвпадение, страната, която е защитена от вятъра и е на завет, се нарича „подветрена“.

8 Думата „ведрò“ споделя произхода си с „вода“, а оттам и с нейните роднини в германските езици (Water в английски, Wasser в немски, vatten в шведски и т.н), които също произлизат от праиндоевропейския корен *wódr. Водата не е етимологично свързана с времето, но между двете понятия има несъмнена метафорична връзка: неслучайно в английски съществува изразът water under the bridge (буквално „вода под моста“), използван за отминали събития, които вече нямат значение. На български пък казваме, че времето „тече“. Както добре знаем, то няма бряг и ни влече, няма как. И тъй, всяко момче всъщност е бъдещ мъж, поет или моряк.

 В рубриката „От дума на дума“ Екатерина Петрова търси актуални, интересни или новопоявили се думи от нашето ежедневие и проследява често изненадващия им произход, развитието на значенията им във времето и взаимовръзките им с близки и далечни езици.

Investigating a forged PDF

Post Syndicated from Matthew Garrett original https://mjg59.dreamwidth.org/73317.html

I had to rent a house for a couple of months recently, which is long enough in California that it pushes you into proper tenant protection law. As landlords tend to do, they failed to return my security deposit within the 21 days required by law, having already failed to provide the required notification that I was entitled to an inspection before moving out. Cue some tedious argumentation with the letting agency, and eventually me threatening to take them to small claims court.

This post is not about that.

Now, under Californian law, the onus is on the landlord to hold and return the security deposit – the agency has no role in this. The only reason I was talking to them is that my lease didn’t mention the name or address of the landlord (another legal violation, but the outcome is just that you get to serve the landlord via the agency). So it was a bit surprising when I received an email from the owner of the agency informing me that they did not hold the deposit and so were not liable – I already knew this.

The odd bit about this, though, is that they sent me another copy of the contract, asserting that it made it clear that the landlord held the deposit. I read it, and instead found a clause reading SECURITY: The security deposit will secure the performance of Tenant’s obligations. IER may, but will not be obligated to, apply all portions of said deposit on account of Tenant’s obligations. Any balance remaining upon termination will be returned to Tenant. Tenant will not have the right to apply the security deposit in payment of the last month’s rent. Security deposit held at IER Trust Account., where IER is International Executive Rentals, the agency in question. Why send me a contract that says you hold the money while you’re telling me you don’t? And then I read further down and found this:
Text reading ENTIRE AGREEMENT: The foregoing constitutes the entire agreement between the parties and may bemodified only in writing signed by all parties. This agreement and any modifications, including anyphotocopy or facsimile, may be signed in one or more counterparts, each of which will be deemed anoriginal and all of which taken together will constitute one and the same instrument. The followingexhibits, if checked, have been made a part of this Agreement before the parties’ execution:۞Exhibit 1:Lead-Based Paint Disclosure (Required by Law for Rental Property Built Prior to 1978)۞Addendum 1 The security deposit will be held by (name removed) and applied, refunded, or forfeited in accordance with the terms of this lease agreement.
Ok, fair enough, there’s an addendum that says the landlord has it (I’ve removed the landlord’s name, it’s present in the original).

Except. I had no recollection of that addendum. I went back to the copy of the contract I had and discovered:
The same text as the previous picture, but addendum 1 is empty
Huh! But obviously I could just have edited that to remove it (there’s no obvious reason for me to, but whatever), and then it’d be my word against theirs. However, I’d been sent the document via RightSignature, an online document signing platform, and they’d added a certification page that looked like this:
A Signature Certificate, containing a bunch of data about the document including a checksum or the original
Interestingly, the certificate page was identical in both documents, including the checksums, despite the content being different. So, how do I show which one is legitimate? You’d think given this certificate page this would be trivial, but RightSignature provides no documented mechanism whatsoever for anyone to verify any of the fields in the certificate, which is annoying but let’s see what we can do anyway.

First up, let’s look at the PDF metadata. pdftk has a dump_data command that dumps the metadata in the document, including the creation date and the modification date. My file had both set to identical timestamps in June, both listed in UTC, corresponding to the time I’d signed the document. The file containing the addendum? The same creation time, but a modification time of this Monday, shortly before it was sent to me. This time, the modification timestamp was in Pacific Daylight Time, the timezone currently observed in California. In addition, the data included two ID fields, ID0 and ID1. In my document both were identical, in the one with the addendum ID0 matched mine but ID1 was different.

These ID tags are intended to be some form of representation (such as a hash) of the document. ID0 is set when the document is created and should not be modified afterwards – ID1 initially identical to ID0, but changes when the document is modified. This is intended to allow tooling to identify whether two documents are modified versions of the same document. The identical ID0 indicated that the document with the addendum was originally identical to mine, and the different ID1 that it had been modified.

Well, ok, that seems like a pretty strong demonstration. I had the “I have a very particular set of skills” conversation with the agency and pointed these facts out, that they were an extremely strong indication that my copy was authentic and their one wasn’t, and they responded that the document was “re-sealed” every time it was downloaded from RightSignature and that would explain the modifications. This doesn’t seem plausible, but it’s an argument. Let’s go further.

My next move was pdfalyzer, which allows you to pull a PDF apart into its component pieces. This revealed that the documents were identical, other than page 3, the one with the addendum. This page included tags entitled “touchUp_TextEdit”, evidence that the page had been modified using Acrobat. But in itself, that doesn’t prove anything – obviously it had been edited at some point to insert the landlord’s name, it doesn’t prove whether it happened before or after the signing.

But in the process of editing, Acrobat appeared to have renamed all the font references on that page into a different format. Every other page had a consistent naming scheme for the fonts, and they matched the scheme in the page 3 I had. Again, that doesn’t tell us whether the renaming happened before or after the signing. Or does it?

You see, when I completed my signing, RightSignature inserted my name into the document, and did so using a font that wasn’t otherwise present in the document (Courier, in this case). That font was named identically throughout the document, except on page 3, where it was named in the same manner as every other font that Acrobat had renamed. Given the font wasn’t present in the document until after I’d signed it, this is proof that the page was edited after signing.

But eh this is all very convoluted. Surely there’s an easier way? Thankfully yes, although I hate it. RightSignature had sent me a link to view my signed copy of the document. When I went there it presented it to me as the original PDF with my signature overlaid on top. Hitting F12 gave me the network tab, and I could see a reference to a base.pdf. Downloading that gave me the original PDF, pre-signature. Running sha256sum on it gave me an identical hash to the “Original checksum” field. Needless to say, it did not contain the addendum.

Why do this? The only explanation I can come up with (and I am obviously guessing here, I may be incorrect!) is that International Executive Rentals realised that they’d sent me a contract which could mean that they were liable for the return of my deposit, even though they’d already given it to my landlord, and after realising this added the addendum, sent it to me, and assumed that I just wouldn’t notice (or that, if I did, I wouldn’t be able to prove anything). In the process they went from an extremely unlikely possibility of having civil liability for a few thousand dollars (even if they were holding the deposit it’s still the landlord’s legal duty to return it, as far as I can tell) to doing something that looks extremely like forgery.

There’s a hilarious followup. After this happened, the agency offered to do a screenshare with me showing them logging into RightSignature and showing the signed file with the addendum, and then proceeded to do so. One minor problem – the “Send for signature” button was still there, just below a field saying “Uploaded: 09/22/25”. I asked them to search for my name, and it popped up two hits – one marked draft, one marked completed. The one marked completed? Didn’t contain the addendum.

comment count unavailable comments

Optimize Amazon EMR runtime for Apache Spark with EMR S3A

Post Syndicated from Giovanni Matteo Fumarola original https://aws.amazon.com/blogs/big-data/optimize-amazon-emr-runtime-for-apache-spark-with-emr-s3a/

With the Amazon EMR 7.10 runtime, Amazon EMR has introduced EMR S3A, an improved implementation of the open source S3A file system connector. This enhanced connector is now automatically set as the default S3 file system connector for Amazon EMR deployment options, including Amazon EMR on EC2, Amazon EMR Serverless, Amazon EMR on Amazon EKS, and Amazon EMR on AWS Outposts, maintaining complete API compatibility with open source Apache Spark.

In the Amazon EMR 7.10 runtime for Apache Spark, the EMR S3A connector exhibits performance comparable to EMRFS for read workloads, as demonstrated by TPC-DS query benchmark. The connector’s most significant performance gains are evident in write operations, with a 7% improvement in static partition overwrites and a 215% improvement for dynamic partition overwrites when compared to EMRFS. In this post, we showcase the enhanced read and write performance advantages of using Amazon EMR 7.10.0 runtime for Apache Spark with EMR S3A as compared to EMRFS and the open source S3A file system connector.

Read workload performance comparison

To evaluate the read performance, we used a test environment based on Amazon EMR runtime version 7.10.0 running Spark 3.5.5 and Hadoop 3.4.1. Our testing infrastructure featured an Amazon Elastic Compute Cloud (Amazon EC2) cluster comprised of nine r5d.4xlarge instances. The primary node has 16 vCPU and 128 GB memory, and the eight core nodes have a total of 128 vCPU and 1024 GB memory.

The performance evaluation was conducted using a comprehensive testing methodology designed to provide accurate and meaningful results. For the source data, we chose the 3 TB scale factor, which contains 17.7 billion records, approximately 924 GB of compressed data partitioned in Parquet file format. The setup instructions and technical details can be found in the GitHub repository. We used Spark’s in-memory data catalog to store metadata for TPC-DS databases and tables.

To produce a fair and accurate comparison between EMR S3A vs. EMRFS and open source S3A implementations, we implemented a three-phase testing approach:

  • Phase 1: Baseline performance:
    • Established a baseline using default Amazon EMR configuration with EMR’s S3A connector
    • Created a reference point for subsequent comparisons
  • Phase 2: EMRFS analysis:
    • Maintained the default file system as EMRFS
    • Preserved other configuration settings
  • Phase 3: Open source S3A testing:
    • Modified only the hadoop-aws.jar file by replacing it with the open source Hadoop S3A 3.4.1 version
    • Maintained identical configurations across other components

This controlled testing environment was crucial for our evaluation for the following reasons:

  • We could isolate the performance impact specifically to the S3A connector implementation
  • It removed potential variables that could skew the results
  • It provided accurate measurements of performance improvements between Amazon’s S3A implementation and the open source alternative

Test execution and results

Throughout the testing process, we maintained consistency in test conditions and configurations, making sure any observed performance differences could be directly attributed to the S3A connector implementation variations. A total of 104 SparkSQL queries were run in 10 iterations sequentially, and an average of each query’s runtime in these 10 iterations was used for comparison. The average of the 10 iterations’ runtime on the Amazon EMR 7.10 runtime for Apache Spark with EMR S3A was 1116.87 seconds, which is 1.08 times faster than open source S3A and comparable with EMRFS. The following figure illustrates the total runtime in seconds.

The following table summarizes the metrics.

Metric OSS S3A EMRFS EMR S3A
Average runtime in seconds 1208.26 1129.64 1116.87
Geometric mean over queries in seconds 7.63 7.09 6.99
Total cost * $6.53 $6.40 $6.15

*Detailed cost estimates are discussed later in this post.

The following chart demonstrates the per-query performance improvement of EMR S3A relative to open source S3A on the Amazon EMR 7.10 runtime for Apache Spark. The extent of the speedup varies from one query to another, with the fastest up to 1.51 times faster for q3, with Amazon EMR S3A outperforming open source S3A. The horizontal axis arranges the TPC-DS 3TB benchmark queries in descending order based on the performance improvement seen with Amazon EMR, and the vertical axis depicts the magnitude of this speedup as a ratio.

Read cost comparison

Our benchmark outputs the total runtime and geometric mean figures to measure the Spark runtime performance. The cost metric can provide us with additional insights. Cost estimates are computed using the following formulas. They factor in Amazon EC2, Amazon Elastic Block Store (Amazon EBS), and Amazon EMR costs, but don’t include Amazon Simple Storage Service (Amazon S3) GET and PUT costs.

  • Amazon EC2 cost (include SSD cost) = number of instances * r5d.4xlarge hourly rate * job runtime in hours
    • r5d.4xlarge hourly rate = $1.152 per hour
  • Root Amazon EBS cost = number of instances * Amazon EBS per GB-hourly rate * root EBS volume size * job runtime in hours
  • Amazon EMR cost = number of instances * r5d.4xlarge Amazon EMR cost * job runtime in hours
    • r5d.4xlarge Amazon EMR cost = $0.27 per hour
  • Total cost = Amazon EC2 cost + root Amazon EBS cost + Amazon EMR cost

The following table summarizes these costs.

Metric EMRFS EMR S3A OSS S3A
Runtime in hours 0.5 0.48 0.51
Number of EC2 instances 9 9 9
Amazon EBS size 0 gb 0 gb 0 gb
Amazon EC2 cost $5.18 $4.98 $5.29
Amazon EBS cost $0.00 $0.00 $0.00
Amazon EMR cost $1.22 $1.17 $1.24
Total cost $6.40 $6.15 $6.53
Cost savings Baseline EMR S3A is 1.04 times better than EMRFS EMR S3A is 1.06 times better than OSS S3A

Write workload performance comparison

We conducted benchmark tests to assess the write performance of the Amazon EMR 7.10 runtime for Apache Spark.

Static table/partition overwrite

We evaluated the static table/partition overwrite write performance of the different file system by executing the following INSERT OVERWRITE Spark SQL query. The SELECT * FROM range(...) clause generated data at execution time. This produced approximately 15 GB of data across exactly 100 Parquet files in Amazon S3.

SET rows=4e9; -- 4 Billion
SET partitions=100;
INSERT OVERWRITE DIRECTORY 's3://${bucket}/perf-test/${trial_id}'
USING PARQUET SELECT * FROM range(0, ${rows}, 1, ${partitions});

The test environment was configured as follows:

  • EMR cluster with emr-7.10.0 release label
  • Single m5d.2xlarge instance (primary group)
  • Eight m5d.2xlarge instances (core group)
  • S3 bucket in the same AWS Region as the EMR cluster
  • The trial_id property used a UUID generator to avoid conflict between test runs

Results

After running 10 trials for each file system, we captured and summarized query runtimes in the following chart. Whereas EMR S3A averaged only 26.4 seconds, the EMRFS and open source S3A averaged 28.4 seconds and 31.4 seconds—a 1.07 times and 1.19 times improvement, respectively.

Dynamic partition overwrite

We also evaluated the write performance by executing the following INSERT OVERWRITE dynamic partition Spark SQL query, which joins TPC-DS 3TB partitioned Parquet data of the table web_sales and date_dim tables, which inserts approximately 2,100 partitions, where each partition contains one Parquet file with a combined size of approximately 31.2 GB in Amazon S3.

SET spark.sql.sources.partitionOverwriteMode=DYNAMIC;
INSERT OVERWRITE TABLE <TABLE_NAME> PARTITION(wsdt_year,wsdt_month, wsdt_day) 
SELECT ws_order_number,ws_quantity,ws_list_price,ws_sales_price,
ws_net_paid_inc_ship_tax,ws_net_profit,dt.d_year as wsdt_year,dt.d_moy 
as wsdt_month,dt.d_dom as wsdt_day FROM web_sales, date_dim dt 
WHERE ws_sold_date_sk = d_date_sk;

The test environment was configured as follows:

  • EMR cluster with emr-7.10.0 release label
  • Single r5d.4xlarge instance (master group)
  • Five r5d.4xlarge instances (core group)
  • Approximately 2,100 partitions with one Parquet file each
  • Combined size of approximately 31.2 GB in Amazon S3

Results

After running 10 trials for each file system, we captured and summarized query runtimes in the following chart. Whereas EMR S3A averaged only 90.9 seconds, the EMRFS and open source S3A averaged 286.4 seconds and 1,438.5 seconds—a 3.15 times and 15.82 times improvement, respectively.

Summary

Amazon EMR consistently enhances its Apache Spark runtime and S3A connector, delivering continuous performance improvements that help big data customers execute analytics workloads more cost-effectively. Beyond performance gains, the strategic shift to S3A introduces critical advantages, including enhanced standardization, improved cross-platform portability, and robust community-driven support—all while maintaining or surpassing the performance benchmarks established by the previous EMRFS implementation.

We recommend that you stay up-to-date with the latest Amazon EMR release to take advantage of the latest performance and feature benefits. Subscribe to the AWS Big Data Blog’s RSS feed to learn more about the Amazon EMR runtime for Apache Spark, configuration best practices, and tuning advice.


About the authors

Giovanni Matteo Fumarola

Giovanni Matteo Fumarola

Giovanni is the Senior Manager for the Amazon EMR Spark and Iceberg group. He is an Apache Hadoop Committer and PMC member. He has been focusing in the big data analytics space since 2013.

Sushil Kumar Shivashankar

Sushil Kumar Shivashankar

Sushil is the Engineering Manager for the Amazon EMR Hadoop and Flink team at Amazon Web Services. With a focus on big data analytics since 2014, he leads development, optimizations, and growth strategies for Hadoop and Flink business in Amazon EMR.

Narayanan Venkateswaran

Narayanan Venkateswaran

Narayanan is a Senior Software Development Engineer in the Amazon EMR group. He works on developing Hadoop components in Amazon EMR. He has over 20 years of work experience in the industry across several companies, including Sun Microsystems, Microsoft, Amazon, and Oracle. Narayanan also holds a PhD in databases with a focus on horizontal scalability in relational stores.

Syed Shameerur Rahman

Syed Shameerur Rahman

Syed is a Software Development Engineer at Amazon EMR. He is interested in highly scalable, distributed computing. He is an active contributor of open source projects like Apache Hive, Apache Tez, Apache ORC, and Apache Hadoop, and has contributed important features and optimizations. During his free time, he enjoys exploring new places and trying new foods.

Rajarshi Sarkar

Rajarshi Sarkar

Rajarshi is a Software Development Engineer at Amazon EMR. He works on cutting-edge features of Amazon EMR and is also involved in open source projects such as Apache Hive, Iceberg, Trino, and Hadoop. In his spare time, he likes to travel, watch movies, and hang out with friends.

Amazon OpenSearch Serverless monitoring: A CloudWatch setup guide

Post Syndicated from Urmila Iyer original https://aws.amazon.com/blogs/big-data/amazon-opensearch-serverless-monitoring-a-cloudwatch-setup-guide/

Amazon OpenSearch Serverless simplifies the deployment and management of OpenSearch workloads by automatically scaling based on your usage patterns. The service considers key metrics such as shard utilization, storage consumption, and CPU usage while maintaining millisecond-level response times, with the simplicity of a serverless environment.

While OpenSearch Serverless handles scaling automatically, implementing robust monitoring remains crucial for understanding usage patterns, optimizing costs, helping to ensure performance, and maintaining reliability. Proactive monitoring helps organizations detect critical issues with the applications or infrastructure in real time and identify root causes quickly.

This post is part of our Amazon OpenSearch service monitoring series, focusing on OpenSearch Serverless workloads and deployments. In this post, we explore commonly used Amazon CloudWatch metrics and alarms for OpenSearch Serverless, walking through the process of selecting relevant metrics, setting appropriate thresholds, and configuring alerts. This guide will provide you with a comprehensive monitoring strategy that complements the serverless nature of your OpenSearch deployment while maintaining full operational visibility.

Key benefits of CloudWatch monitoring for OpenSearch Serverless

Implementing CloudWatch monitoring for your OpenSearch Serverless collections offers several key advantages:

  • Near real-time performance monitoring – CloudWatch provides near real-time monitoring, enabling you to track your OpenSearch Serverless collections’ performance as they operate. This immediate visibility allows for swift detection of anomalies or performance issues, enabling prompt response to potential problems.
  • Efficient error diagnosis – You can quickly identify and address common errors without extensive log analysis. For instance, by monitoring ingestion request errors, you can preemptively mitigate bulk indexing request failures.
  • Proactive alerting system – Use the CloudWatch alarm functionality in conjunction with Amazon Simple Notification Service (SNS) to set up custom alerts. By defining specific thresholds for critical metrics, you can receive instant notifications through email or SMS when your OpenSearch Serverless collections approach or exceed these limits.
  • Comprehensive historical analysis – The data retention capabilities of CloudWatch allow for in-depth historical analysis. This helps you to identify long-term performance trends, recognize recurring patterns in resource utilization and optimize workload distribution based on historical insights.

Solution overview

Understanding which metrics to monitor in OpenSearch Serverless helps optimize your system’s performance and reliability. This guide explains the key metrics to monitor, their significance, how to determine appropriate thresholds, and the step-by-step process for setting up alarms. Understanding these fundamentals will help you establish effective monitoring for your OpenSearch Serverless collections and help maintain optimal performance and reliability.

Prerequisites

Before getting started, you must have the following prerequisites:

CloudWatch metrics and recommended alarms for OpenSearch Serverless

The following table summarizes key CloudWatch metrics for OpenSearch Serverless, including recommended alarm thresholds, metric descriptions, and applicable workload types.

Alarm Metric Level Metric Description Alarm Description Use case
IndexingOCU maximum is >= 10 for 5 minutes, three consecutive times Account Level

Serverless compute capacity is measured in OpenSearch Compute Units (OCUs). Each OCU is a combination of 6 GiB of memory and corresponding virtual CPU (vCPU), in addition to data transfer to Amazon Simple Storage Service (Amazon S3).

The IndexingOCU metric reports the number of OCUs used for data ingestion across all collections.

This alarm will alert you when Indexing OCUs scale upto / beyond 10 for more than 15 minutes. Monitor and Optimize Costs
SearchOCU maximum is >= 10 for 5 minutes, three consecutive times Account Level

Serverless compute capacity is measured in OCUs. Each OCU is a combination of 6 GiB of memory and corresponding virtual CPU (vCPU), in addition to data transfer to Amazon S3.

The SearchOCU metric reports the number of OCUs used to search collection data across all collections.

This alarm will alert you when Search OCUs scale upto / beyond 10 for more than 15 minutes. Monitor and Optimize Costs
IngestionRequestLatency maximum is >= 3 secs for 1 minutes, five consecutive times. Collection Level The IngestionRequestLatency metric reports the latency, in seconds, for bulk write operations to a collection. This alarm monitors the maximum latency of bulk write operations to a collection. It triggers when the maximum IngestionRequestLatency exceeds 3 seconds for five consecutive 1-minute intervals (for a total of 5 minutes). This indicates a sustained performance degradation in data ingestion operations, which could impact application performance and data availability. This metric might be crucial to monitor for log-based workloads, where indexing time is critical.
SearchRequestLatency maximum is >= 2 secs for 1 minutes, five consecutive times. Collection Level The SearchRequestLatency metric reports the latency, in seconds, that it takes to complete a search operation against a collection. This alarm monitors the maximum latency of search operations against a collection. It triggers when the maximum SearchRequestLatency exceeds 2 seconds for five consecutive 1-minute intervals (for a total of 5 minutes). Consistently high search latency indicates performance issues that could degrade user experience and application responsiveness. This metric might be crucial to monitor for vector and search-based workloads, where search time is critical.
IngestionRequestErrors sum is >= 100 errors for 1 minute, five consecutive times Collection Level The IngestionRequestErrors metric reports the total number of bulk indexing request errors to a collection. OpenSearch Serverless emits this metric when there are bulk indexing request failures, such as an authentication or availability issue. This alarm monitors the total count of failed bulk indexing operations to a collection. It triggers when the number of IngestionRequestErrors equals or exceeds 100 errors for five consecutive 1-minute intervals (for a total of 5 minutes). Persistent ingestion errors indicate systemic issues that could lead to data loss or inconsistency.
SearchRequestErrors sum is >= 50 errors for 1 minute, five consecutive times Collection Level The SearchRequestErrors metric reports the total number of query errors per minute for a collection. This alarm monitors the total count of failed search query operations in a collection. It triggers when the number of SearchRequestErrors equals or exceeds 50 errors for five consecutive 1-minute intervals (for a total of 5 minutes). Persistent search errors indicate potential issues that could impact application functionality and user experience.
ActiveCollection minimum is 0 for 1 minutes, three consecutive times. Collection Level This metric indicates whether a collection is active. A value of 1 means that the collection is in an ACTIVE state. This value is emitted upon successful creation of a collection and remains 1 until you delete the collection. The metric can’t have a value of 0. The alarm triggers when the metric is missing for three consecutive 1-minute intervals (for a total of 3 minutes). Because an active collection always emits a value of 1, missing data indicates the collection has been deleted or is experiencing serious issues.
Note: Make sure to setup the CloudWatch alarm so that it will treat missing data as breaching.
Monitor Availability of Collection

The specific threshold values mentioned are examples. However, you may need to adjust these thresholds based on the unique requirements and SLAs of your own applications and workloads running on OpenSearch Serverless.

To decide when to raise the global OCU limits, you should regularly review the IndexingOCU and SearchOCU metrics at the account level. If you notice the metrics consistently approaching the set threshold, it’s a good indication that you should consider increasing the overall account limits to accommodate your growing usage.

Additionally, monitor the collection-level metrics like IngestionRequestLatency and SearchRequestLatency. If you notice certain collections have consistently high latency, it might be a sign that the OCU allocation for those specific collections is insufficient. In such cases, you could consider increasing the OCU limits for those high-usage collections, rather than raising the global account limits.

By closely monitoring both the account-level and collection-level metrics, you can make informed decisions about when and how to adjust your OCU limits to maintain optimal performance and cost efficiency for your OpenSearch Serverless deployment.

Steps to create a CloudWatch alarm

CloudWatch Alarms can be created using any of the following methods:

Detailed steps and a / sample code snippet for each method are provided in the following sections.

Using the console

The AWS Management Console provides a user-friendly, visual interface for creating CloudWatch alarms. Follow these step-by-step instructions to set up your alarm through the console.

  1. Navigate to the CloudWatch console
  2. In the navigation pane, choose Alarms and then, All alarms.
  3. Choose Create alarm.

Create an alarm

  1. Choose Select Metric.
  2. Select the namespace AOSS 

Choose CloudWatch Namespace

  1. To setup alerting on IndexingOCU across all collections, navigate to ClientId and select the metric.
  2. Under Conditions:
    1. For Statistic: Select Maximum.
    2. For Period: Select 5 minutes.
    3. For Threshold type: Choose Static and Greater.

Specify metric and conditions

  1. Choose Next. Under Notification, select an SNS topic to notify when the alarm is in ALARM state, OK state, or INSUFFICIENT_DATA state.

Configure Actions

  1. When finished, choose Next. Enter a name and description for the alarm. The name must contain only UTF-8 characters, and can’t contain ASCII control characters. The description can include markdown formatting, which is displayed only in the alarm Details tab in the CloudWatch console. The markdown can be useful to add links to runbooks or other internal resources. Then choose Next.
  2. Under Preview and create, confirm that the information and conditions are what you want, then choose Create alarm.

For detailed documentation, refer to Create a CloudWatch alarm based on a static threshold.

Using the AWS CLI

For those who prefer command-line interfaces or need to automate alarm creation, the AWS CLI offers an efficient alternative. This section demonstrates how to create a CloudWatch alarm using a single CLI command.

To set up a CloudWatch alarm using the AWS CLI, you can use the put-metric-alarm command. The following example demonstrates how to create an alarm that sends an Amazon SNS email when the IndexingOCU exceeds 2 for 15 minutes at the account level. Replace [region] and [account-id] with your AWS Region and account ID.

aws cloudwatch put-metric-alarm \
--alarm-description '# IndexingOCU scaling out' \
--actions-enabled \
--alarm-actions 'arn:aws:sns:[region]:[account-id]:SecurityHubRecurringSummary' \
--metric-name 'IndexingOCU' \
--namespace 'AWS/AOSS' \
--statistic 'Maximum' \
--dimensions '[{"Name":"ClientId","Value":"[account-id]"}]' \
--period 300 \
--evaluation-periods 3 \
--datapoints-to-alarm 3 \
--threshold 2 \
--comparison-operator 'GreaterThanThreshold' \
--treat-missing-data 'ignore'

CloudFormation JSON

Infrastructure as Code (IaC) enables version-controlled, repeatable deployments. This JSON template shows how to define a CloudWatch alarm using AWS CloudFormation, suitable for those who prefer JSON syntax for their IaC implementations.

Replace [region] and [account-id] with your AWS Region and account ID.

{
    "Type": "AWS::CloudWatch::Alarm",
    "Properties": {
        "AlarmDescription": "# IndexingOCU scaling out",
        "ActionsEnabled": true,
        "OKActions": [],
        "AlarmActions": [
            "arn:aws:sns:[region]:[account-id]:SecurityHubRecurringSummary"
        ],
        "InsufficientDataActions": [],
        "MetricName": "IndexingOCU",
        "Namespace": "AWS/AOSS",
        "Statistic": "Maximum",
        "Dimensions": [
            {
                "Name": "ClientId",
                "Value": "[account-id]"
            }
        ],
        "Period": 300,
        "EvaluationPeriods": 3,
        "DatapointsToAlarm": 3,
        "Threshold": 2,
        "ComparisonOperator": "GreaterThanThreshold",
        "TreatMissingData": "ignore"
    }
}

CloudFormation YAML

For teams that prefer YAML’s more readable format, this section provides the equivalent CloudFormation template in YAML. The template creates the same CloudWatch alarm with identical configurations as the JSON version.

Replace [region] and [account-id] with your AWS Region and account ID.

Type: AWS::CloudWatch::Alarm
Properties:
    AlarmDescription: "# IndexingOCU scaling out"
    ActionsEnabled: true
    OKActions: []
    AlarmActions:
        - arn:aws:sns:[region]:[account-id]:SecurityHubRecurringSummary
    InsufficientDataActions: []
    MetricName: IndexingOCU
    Namespace: AWS/AOSS
    Statistic: Maximum
    Dimensions:
        - Name: ClientId
          Value: "[account-id]"
    Period: 300
    EvaluationPeriods: 3
    DatapointsToAlarm: 3
    Threshold: 2
    ComparisonOperator: GreaterThanThreshold
    TreatMissingData: ignore

CloudWatch dashboards

You can use Amazon CloudWatch dashboards to monitor multiple resources in a unified view. For example, the following dashboard provides a consolidated view of OpenSearch Serverless OCU usage, helping you track and manage costs.

View dashboards

Clean up

To avoid incurring unintended future charges, delete the following resources that were created as part of solution walk-through of this post:

  • CloudWatch alarms
  • CloudFormation stacks
  • SNS topics

Conclusion

Effective monitoring helps maintain optimal performance and reliability of your OpenSearch Serverless collections. By implementing the CloudWatch alarms and monitoring strategies outlined in this post, you can work towards proactively identifying and responding to performance issues before they impact your applications, optimize costs by tracking OCU usage patterns, support high availability objectives by monitoring collection health and error rates, and help maintain consistent performance through latency monitoring. Remember that the thresholds suggested in this guide serve as a starting point, you should adjust them based on your specific use cases, performance requirements, and budget constraints. Regular review and refinement of these alarms will help you maintain an efficient and cost-effective OpenSearch Serverless deployment.

Related links

Monitoring Amazon OpenSearch Serverless

Create a CloudWatch alarm based on a static threshold


About the authors

Urmila Iyer

Urmila Iyer

Urmila is a Technical Account Manager at AWS, where she partners with enterprise customers to understand their business objectives and architect solutions that drive meaningful outcomes. With 15 years of experience in IT, including 6 years at AWS, she specializes in data-driven solutions, bringing enthusiasm and expertise to data analytics projects using OpenSearch and real-time analytics platforms.

Parth Shah

Parth Shah

Parth is a Senior Solutions Architect at AWS passionate about solving complex data challenges for strategic customers. As a analytics enthusiast, he helps organizations make sense of their data through innovative cloud solutions, with deep expertise in OpenSearch implementations.
Outside of work, he enjoys spending time with family, exploring different cuisines and playing cricket.

[$] Canceling asynchronous Rust

Post Syndicated from daroc original https://lwn.net/Articles/1036924/

Asynchronous Rust code has what Rain Paharia calls a “universal cancellation
protocol
“, meaning that any asynchronous code can be interrupted in the same
way. They claim
that this is both a useful feature when used deliberately, and a source of
errors when done by accident. They presented
about this problem at

RustConf 2025
, offering a handful of techniques to avoid introducing bugs into
asynchronous Rust code.

Touring MikroTik in Latvia to See How they Make Awesome Networking Gear

Post Syndicated from Patrick Kennedy original https://www.servethehome.com/touring-mikrotik-in-latvia-to-see-how-they-make-networking-gear/

We take you on a tour of the MikroTik offices in Riga Latvia and to a contract manufacturer to see how networking gear is built

The post Touring MikroTik in Latvia to See How they Make Awesome Networking Gear appeared first on ServeTheHome.

The collective thoughts of the interwebz