{"id":30119699,"url":"https://github.com/rivendael/fastmssql","last_synced_at":"2026-02-20T06:00:52.566Z","repository":{"id":308251470,"uuid":"1031677909","full_name":"Rivendael/FastMssql","owner":"Rivendael","description":"High performance async Mssql library for Python.","archived":false,"fork":false,"pushed_at":"2026-02-12T04:10:26.000Z","size":1068,"stargazers_count":16,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-02-12T14:05:49.284Z","etag":null,"topics":["asynchronous","microsoft-sql-server","mssql","mssql-database","multithreading","performance-optimization","python","python3","rust-lang"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Rivendael.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-04T07:03:07.000Z","updated_at":"2026-02-12T04:09:33.000Z","dependencies_parsed_at":"2025-09-04T05:36:44.758Z","dependency_job_id":"cd5141f0-be35-4168-83b9-41ea82a226b8","html_url":"https://github.com/Rivendael/FastMssql","commit_stats":null,"previous_names":["rivendael/pymssql-rs","rivendael/fastmssql"],"tags_count":53,"template":false,"template_full_name":null,"purl":"pkg:github/Rivendael/FastMssql","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rivendael%2FFastMssql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rivendael%2FFastMssql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rivendael%2FFastMssql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rivendael%2FFastMssql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Rivendael","download_url":"https://codeload.github.com/Rivendael/FastMssql/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rivendael%2FFastMssql/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29642902,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-20T05:21:04.652Z","status":"ssl_error","status_checked_at":"2026-02-20T05:21:04.238Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asynchronous","microsoft-sql-server","mssql","mssql-database","multithreading","performance-optimization","python","python3","rust-lang"],"created_at":"2025-08-10T12:34:01.309Z","updated_at":"2026-02-20T06:00:52.560Z","avatar_url":"https://github.com/Rivendael.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FastMSSQL ⚡\n\nFastMSSQL is an async Python library for Microsoft SQL Server (MSSQL), built in Rust.\nUnlike standard libaries, it uses a native SQL Server client—no ODBC required—simplifying installation on Windows, macOS, and Linux.\nGreat for data ingestion, bulk inserts, and large-scale query workloads.\n\n[![Python Versions](https://img.shields.io/pypi/pyversions/fastmssql)](https://pypi.org/project/fastmssql/)\n\n[![License](https://img.shields.io/badge/license-MIT%20-green)](LICENSE)\n\n[![Unit Tests](https://github.com/Rivendael/fastmssql/actions/workflows/unittests.yml/badge.svg)](https://github.com/Rivendael/fastmssql/actions/workflows/unittests.yml)\n\n[![Latest Release](https://img.shields.io/github/v/release/Rivendael/fastmssql)](https://github.com/Rivendael/fastmssql/releases)\n\n[![Platform](https://img.shields.io/badge/platform-Windows%20|%20Linux%20|%20macOS-lightgrey)](https://github.com/Rivendael/fastmssql)\n\n[![Rust Backend](https://img.shields.io/badge/backend-rust-orange)](https://github.com/Rivendael/pymssql-rs)\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Features](#features)\n- [Key API methods](#key-api-methods)\n- [Installation](#installation)\n- [Quick start](#quick-start)\n- [Explicit Connection Management](#explicit-connection-management)\n- [Usage](#usage)\n- [Performance tips](#performance-tips)\n- [Examples \u0026 benchmarks](#examples--benchmarks)\n- [Troubleshooting](#troubleshooting)\n- [Contributing](#contributing)\n- [License](#license)\n- [Third‑party attributions](#third%E2%80%91party-attributions)\n- [Acknowledgments](#acknowledgments)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Features\n\n- High performance: optimized for very high RPS and low overhead\n- Rust core: memory‑safe and reliable, tuned Tokio runtime\n- No ODBC: native SQL Server client, no external drivers needed\n- Azure authentication: Service Principal, Managed Identity, and access token support (**BETA**)\n- Connection pooling: bb8‑based, smart defaults (default max_size=20, min_idle=2)\n- Async first: clean async/await API with `async with` context managers\n- Strong typing: fast conversions for common SQL Server types\n- Thread‑safe: safe to use in concurrent apps\n- Cross‑platform: Windows, macOS, Linux\n- Batch operations: high-performance bulk inserts and batch query execution\n- Apache Arrow support\n\n## Installation\n\n### From PyPI (recommended)\n\n```bash\npip install fastmssql\n```\n\n### Optional dependencies\n\n**Apache Arrow support** (for `to_arrow()` method):\n\n```bash\npip install fastmssql[arrow]\n```\n\n### Prerequisites\n\n- Python 3.11 to 3.14\n- Microsoft SQL Server (any recent version)\n\n## Quick start\n\n### Basic async usage\n\n```python\nimport asyncio\nfrom fastmssql import Connection\n\nasync def main():\n    conn_str = \"Server=localhost;Database=master;User Id=myuser;Password=mypass\"\n    async with Connection(conn_str) as conn:\n        # SELECT: use query() -\u003e rows()\n        result = await conn.query(\"SELECT @@VERSION as version\")\n        for row in result.rows():\n            print(row['version'])\n\n        # Pool statistics (tuple: connected, connections, idle, max_size, min_idle)\n        connected, connections, idle, max_size, min_idle = await conn.pool_stats()\n        print(f\"Pool: connected={connected}, size={connections}/{max_size}, idle={idle}, min_idle={min_idle}\")\n\nasyncio.run(main())\n```\n\n## Explicit Connection Management\n\nWhen not utilizing Python's context manager (async with), **FastMssql** uses *lazy connection initialization*:\nif you call `query()` or `execute()` on a new `Connection`, the underlying pool is created if not already present.\n\nFor more control, you can explicitly connect and disconnect:\n\n```python\nimport asyncio\nfrom fastmssql import Connection\n\nasync def main():\n    conn_str = \"Server=localhost;Database=master;User Id=myuser;Password=mypass\"\n    conn = Connection(conn_str)\n\n    # Explicitly connect\n    await conn.connect()\n    assert await conn.is_connected()\n\n    # Run queries\n    result = await conn.query(\"SELECT 42 as answer\")\n    print(result.rows()[0][\"answer\"])  # -\u003e 42\n\n    # Explicitly disconnect\n    await conn.disconnect()\n    assert not await conn.is_connected()\n\nasyncio.run(main())\n```\n\n## Usage\n\n### Connection options\n\nYou can connect either with a connection string or individual parameters.\n\n1) Connection string\n\n```python\nimport asyncio\nfrom fastmssql import Connection\n\nasync def main():\n    conn_str = \"Server=localhost;Database=master;User Id=myuser;Password=mypass\"\n    async with Connection(connection_string=conn_str) as conn:\n        rows = (await conn.query(\"SELECT DB_NAME() as db\")).rows()\n        print(rows[0]['db'])\n\nasyncio.run(main())\n```\n\n1) Individual parameters\n\n```python\nimport asyncio\nfrom fastmssql import Connection\n\nasync def main():\n    async with Connection(\n        server=\"localhost\",\n        database=\"master\",\n        username=\"myuser\",\n        password=\"mypassword\"\n    ) as conn:\n        rows = (await conn.query(\"SELECT SUSER_SID() as sid\")).rows()\n        print(rows[0]['sid'])\n\nasyncio.run(main())\n```\n\nNote: Windows authentication (Trusted Connection) is currently not supported. Use SQL authentication (username/password).\n\n### Azure Authentication (BETA)\n\n🧪 **This is a beta feature.** Azure authentication functionality is experimental and may change in future versions.\n\nFastMSSSQL supports Azure Active Directory (AAD) authentication for Azure SQL Database and Azure SQL Managed Instance. You can authenticate using Service Principals, Managed Identity, or access tokens.\n\n#### Service Principal Authentication\n\n```python\nimport asyncio\nfrom fastmssql import Connection, AzureCredential\n\nasync def main():\n    # Create Azure credential using Service Principal\n    azure_cred = AzureCredential.service_principal(\n        client_id=\"your-client-id\",\n        client_secret=\"your-client-secret\", \n        tenant_id=\"your-tenant-id\"\n    )\n    \n    async with Connection(\n        server=\"yourserver.database.windows.net\",\n        database=\"yourdatabase\",\n        azure_credential=azure_cred\n    ) as conn:\n        result = await conn.query(\"SELECT GETDATE() as current_time\")\n        for row in result.rows():\n            print(f\"Connected! Current time: {row['current_time']}\")\n\nasyncio.run(main())\n```\n\n#### Managed Identity Authentication\n\nFor Azure resources (VMs, Function Apps, App Service, etc.):\n\n```python\nimport asyncio\nfrom fastmssql import Connection, AzureCredential\n\nasync def main():\n    # System-assigned managed identity\n    azure_cred = AzureCredential.managed_identity()\n    \n    # Or user-assigned managed identity\n    # azure_cred = AzureCredential.managed_identity(client_id=\"user-assigned-identity-client-id\")\n    \n    async with Connection(\n        server=\"yourserver.database.windows.net\",\n        database=\"yourdatabase\",\n        azure_credential=azure_cred\n    ) as conn:\n        result = await conn.query(\"SELECT USER_NAME() as user_name\")\n        for row in result.rows():\n            print(f\"Connected as: {row['user_name']}\")\n\nasyncio.run(main())\n```\n\n#### Access Token Authentication\n\nIf you already have an access token from another Azure service:\n\n```python\nimport asyncio\nfrom fastmssql import Connection, AzureCredential\n\nasync def main():\n    # Use a pre-obtained access token\n    access_token = \"your-access-token\"\n    azure_cred = AzureCredential.access_token(access_token)\n    \n    async with Connection(\n        server=\"yourserver.database.windows.net\",\n        database=\"yourdatabase\",\n        azure_credential=azure_cred\n    ) as conn:\n        result = await conn.query(\"SELECT 1 as test\")\n        print(\"Connected with access token!\")\n\nasyncio.run(main())\n```\n\n#### Default Azure Credential\n\nUses the Azure credential chain (environment variables → managed identity → Azure CLI → Azure PowerShell):\n\n```python\nimport asyncio\nfrom fastmssql import Connection, AzureCredential\n\nasync def main():\n    # Use default Azure credential chain\n    azure_cred = AzureCredential.default()\n    \n    async with Connection(\n        server=\"yourserver.database.windows.net\",\n        database=\"yourdatabase\",\n        azure_credential=azure_cred\n    ) as conn:\n        result = await conn.query(\"SELECT 1 as test\")\n        print(\"Connected with default credentials!\")\n\nasyncio.run(main())\n```\n\n**Prerequisites for Azure Authentication:**\n- Azure SQL Database or Azure SQL Managed Instance\n- Service Principal with appropriate SQL Database permissions\n- For Managed Identity: Azure resource with managed identity enabled\n- For Default credential: Azure CLI installed and authenticated (`az login`)\n\nSee [examples/azure_auth_example.py](examples/azure_auth_example.py) for comprehensive usage examples.\n\n### Working with data\n\n```python\nimport asyncio\nfrom fastmssql import Connection\n\nasync def main():\n    async with Connection(\"Server=.;Database=MyDB;User Id=sa;Password=StrongPwd;\") as conn:\n        # SELECT (returns rows)\n        users = (await conn.query(\n            \"SELECT id, name, email FROM users WHERE active = 1\"\n        )).rows()\n        for u in users:\n            print(f\"User {u['id']}: {u['name']} ({u['email']})\")\n\n        # INSERT / UPDATE / DELETE (returns affected row count)\n        inserted = await conn.execute(\n            \"INSERT INTO users (name, email) VALUES (@P1, @P2)\",\n            [\"Jane\", \"jane@example.com\"],\n        )\n        print(f\"Inserted {inserted} row(s)\")\n\n        updated = await conn.execute(\n            \"UPDATE users SET last_login = GETDATE() WHERE id = @P1\",\n            [123],\n        )\n        print(f\"Updated {updated} row(s)\")\n\nasyncio.run(main())\n```\n\nParameters use positional placeholders: `@P1`, `@P2`, ... Provide values as a list in the same order.\n\n### Batch operations\n\nFor high-throughput scenarios, use batch methods to reduce network round-trips:\n\n```python\nimport asyncio\nfrom fastmssql import Connection\n\nasync def main_fetching():\n    # Replace with your actual connection string\n    async with Connection(\"Server=.;Database=MyDB;User Id=sa;Password=StrongPwd;\") as conn:\n\n        # --- 1. Prepare Data for Demonstration ---\n        columns = [\"name\", \"email\", \"age\"]\n        data_rows = [\n            [\"Alice Johnson\", \"alice@example.com\", 28],\n            [\"Bob Smith\", \"bob@example.com\", 32],\n            [\"Carol Davis\", \"carol@example.com\", 25],\n            [\"David Lee\", \"david@example.com\", 35],\n            [\"Eva Green\", \"eva@example.com\", 29]\n        ]\n        await conn.bulk_insert(\"users\", columns, data_rows)\n\n        # --- 2. Execute Query and Retrieve the Result Object ---\n        print(\"\\n--- Result Object Fetching (fetchone, fetchmany, fetchall) ---\")\n\n        # The Result object is returned after the awaitable query executes.\n        result = await conn.query(\"SELECT name, age FROM users ORDER BY age DESC\")\n\n        # fetchone(): Retrieves the next single row synchronously.\n        oldest_user = result.fetchone()\n        if oldest_user:\n            print(f\"1. fetchone: Oldest user is {oldest_user['name']} (Age: {oldest_user['age']})\")\n\n        # fetchmany(2): Retrieves the next set of rows synchronously.\n        next_two_users = result.fetchmany(2)\n        print(f\"2. fetchmany: Retrieved {len(next_two_users)} users: {[r['name'] for r in next_two_users]}.\")\n\n        # fetchall(): Retrieves all remaining rows synchronously.\n        remaining_users = result.fetchall()\n        print(f\"3. fetchall: Retrieved all {len(remaining_users)} remaining users: {[r['name'] for r in remaining_users]}.\")\n\n        # Exhaustion Check: Subsequent calls return None/[]\n        print(f\"4. Exhaustion Check (fetchone): {result.fetchone()}\")\n        print(f\"5. Exhaustion Check (fetchmany): {result.fetchmany(1)}\")\n\n        # --- 3. Batch Commands for multiple operations ---\n        print(\"\\n--- Batch Commands (execute_batch) ---\")\n        commands = [\n            (\"UPDATE users SET last_login = GETDATE() WHERE name = @P1\", [\"Alice Johnson\"]),\n            (\"INSERT INTO user_logs (action, user_name) VALUES (@P1, @P2)\", [\"login\", \"Alice Johnson\"])\n        ]\n\n        affected_counts = await conn.execute_batch(commands)\n        print(f\"Updated {affected_counts[0]} users, inserted {affected_counts[1]} logs\")\n\nasyncio.run(main_fetching())\n```\n\n### Apache Arrow\n\nConvert query results to Apache Arrow tables for efficient bulk data processing and interoperability with data science tools:\n\n```python\nimport asyncio\nfrom fastmssql import Connection\n\nasync def main():\n    conn_str = \"Server=localhost;Database=master;User Id=myuser;Password=mypass\"\n    async with Connection(conn_str) as conn:\n        # Execute query and convert to Arrow\n        result = await conn.query(\"SELECT id, name, salary FROM employees\")\n        arrow_table = result.to_arrow()\n        \n        # Arrow Table enables:\n        # - Efficient columnar storage and compute\n        # - Integration with Pandas, DuckDB, Polars\n        # - Parquet/ORC serialization\n        df = arrow_table.to_pandas()  # Convert to pandas DataFrame\n        print(df)\n        \n        # Write to Parquet for long-term storage\n        import pyarrow.parquet as pq\n        pq.write_table(arrow_table, \"employees.parquet\")\n        \n        # Or use with DuckDB for analytical queries\n        import duckdb\n        result = duckdb.from_arrow(arrow_table).filter(\"salary \u003e 50000\").execute()\n        print(result.fetchall())\n```\n\n**Requirements**: Install PyArrow with `pip install pyarrow`\n\nNote: Results are converted eagerly into Arrow arrays. For very large datasets, consider chunking queries or using iteration-based processing instead.\n\n### Connection pooling\n\nTune the pool to fit your workload. Constructor signature:\n\n```python\nfrom fastmssql import PoolConfig\n\nconfig = PoolConfig(\n    max_size=20,              # max connections in pool\n    min_idle=5,               # keep at least this many idle\n    max_lifetime_secs=3600,   # recycle connections after 1h\n    idle_timeout_secs=600,    # close idle connections after 10m\n    connection_timeout_secs=30\n)\n```\n\nPresets:\n\n```python\none   = PoolConfig.one()                     # max_size=1,  min_idle=1  (single connection)\nlow   = PoolConfig.low_resource()            # max_size=3,  min_idle=1  (constrained environments)\ndev   = PoolConfig.development()             # max_size=5,  min_idle=1  (local development)\nhigh  = PoolConfig.high_throughput()         # max_size=25, min_idle=8  (high-throughput workloads)\nmaxp  = PoolConfig.performance()             # max_size=30, min_idle=10 (maximum performance)\n\n# ✨ RECOMMENDED: Adaptive pool sizing based on your concurrency\nadapt = PoolConfig.adaptive(20)              # Dynamically sized for 20 concurrent workers\n                                             # Formula: max_size = ceil(workers * 1.2) + 5\n```\n\n**⚡ Performance Tip**: Use `PoolConfig.adaptive(n)` where `n` is your expected concurrent workers/tasks. This prevents connection pool lock contention that can degrade performance with oversized pools.\n\nApply to a connection:\n\n```python\n# Recommended: adaptive sizing\nasync with Connection(conn_str, pool_config=PoolConfig.adaptive(20)) as conn:\n    rows = (await conn.query(\"SELECT 1 AS ok\")).rows()\n\n# Or use presets\nasync with Connection(conn_str, pool_config=PoolConfig.high_throughput()) as conn:\n    rows = (await conn.query(\"SELECT 1 AS ok\")).rows()\n```\n\nDefault pool (if omitted): `max_size=15`, `min_idle=3`.\n\n\n### Transactions\n\nFor workloads that require SQL Server transactions with guaranteed connection isolation, use the `Transaction` class. Unlike `Connection` (which uses connection pooling), `Transaction` maintains a dedicated, non-pooled connection for the lifetime of the transaction. This ensures all operations within the transaction run on the same connection, preventing connection-switching issues.\n\n#### Automatic transaction control (recommended)\n\nUse the context manager for automatic `BEGIN`, `COMMIT`, and `ROLLBACK`:\n\n```python\nimport asyncio\nfrom fastmssql import Transaction\n\nasync def main():\n    conn_str = \"Server=localhost;Database=master;User Id=myuser;Password=mypass\"\n    \n    async with Transaction(conn_str) as transaction:\n        # Automatically calls BEGIN\n        await transaction.execute(\n            \"INSERT INTO orders (customer_id, total) VALUES (@P1, @P2)\",\n            [123, 99.99]\n        )\n        await transaction.execute(\n            \"INSERT INTO order_items (order_id, product_id, qty) VALUES (@P1, @P2, @P3)\",\n            [1, 456, 2]\n        )\n        # Automatically calls COMMIT on successful exit\n        # or ROLLBACK if an exception occurs\n\nasyncio.run(main())\n```\n\n#### Manual transaction control\n\nFor more control, explicitly call `begin()`, `commit()`, and `rollback()`:\n\n```python\nimport asyncio\nfrom fastmssql import Transaction\n\nasync def main():\n    conn_str = \"Server=localhost;Database=master;User Id=myuser;Password=mypass\"\n    transaction = Transaction(conn_str)\n    \n    try:\n        await transaction.begin()\n        \n        result = await transaction.query(\"SELECT @@VERSION as version\")\n        print(result.rows()[0]['version'])\n        \n        await transaction.execute(\"UPDATE accounts SET balance = balance - @P1 WHERE id = @P2\", [50, 1])\n        await transaction.execute(\"UPDATE accounts SET balance = balance + @P1 WHERE id = @P2\", [50, 2])\n        \n        await transaction.commit()\n    except Exception as e:\n        await transaction.rollback()\n        raise\n    finally:\n        await transaction.close()\n\nasyncio.run(main())\n```\n\n#### Key differences: Transaction vs Connection\n\n| Feature | Transaction | Connection |\n|---------|-------------|------------|\n| Connection | Dedicated, non-pooled | Pooled (bb8) |\n| Use case | SQL transactions, ACID operations | General queries, connection reuse |\n| Isolation | Single connection per instance | Connection may vary per operation |\n| Pooling | None (direct TcpStream) | Configurable pool settings |\n| Lifecycle | Held until `.close()` or context exit | Released to pool after each operation |\n\nChoose `Transaction` when you need guaranteed transaction isolation; use `Connection` for typical queries and high-concurrency workloads with connection pooling.\n\n\n### SSL/TLS\n\nFor `Required` and `LoginOnly` encryption, you must specify how to validate the server certificate:\n\n**Option 1: Trust Server Certificate** (development/self-signed certs):\n\n```python\nfrom fastmssql import SslConfig, EncryptionLevel, Connection\n\nssl = SslConfig(\n    encryption_level=EncryptionLevel.Required,\n    trust_server_certificate=True\n)\n\nasync with Connection(conn_str, ssl_config=ssl) as conn:\n    ...\n```\n\n**Option 2: Custom CA Certificate** (production):\n\n```python\nfrom fastmssql import SslConfig, EncryptionLevel, Connection\n\nssl = SslConfig(\n    encryption_level=EncryptionLevel.Required,\n    ca_certificate_path=\"/path/to/ca-cert.pem\"\n)\n\nasync with Connection(conn_str, ssl_config=ssl) as conn:\n    ...\n```\n\n**Note**: `trust_server_certificate` and `ca_certificate_path` are mutually exclusive.\n\nHelpers:\n\n- `SslConfig.development()` – encrypt, trust all (dev only)\n- `SslConfig.with_ca_certificate(path)` – use custom CA\n- `SslConfig.login_only()` / `SslConfig.disabled()` – legacy modes\n- `SslConfig.disabled()` – no encryption (not recommended)\n\n## Performance tips\n\n### 1. Use adaptive pool sizing for optimal concurrency\n\nMatch your pool size to actual concurrency to avoid connection pool lock contention:\n\n```python\nimport asyncio\nfrom fastmssql import Connection, PoolConfig\n\nasync def worker(conn_str, cfg):\n    async with Connection(conn_str, pool_config=cfg) as conn:\n        for _ in range(1000):\n            result = await conn.query(\"SELECT 1 as v\")\n            # ✅ Good: Lazy iteration (minimal GIL hold per row)\n            for row in result:\n                process(row)\n\nasync def main():\n    conn_str = \"Server=.;Database=master;User Id=sa;Password=StrongPwd;\"\n    num_workers = 32\n    \n    # ✅ Adaptive sizing prevents pool contention\n    cfg = PoolConfig.adaptive(num_workers)  # → max_size=43 for 32 workers\n    \n    await asyncio.gather(*[worker(conn_str, cfg) for _ in range(num_workers)])\n\nasyncio.run(main())\n```\n\n### 2. Use iteration for large result sets (not `.rows()`)\n\n```python\nresult = await conn.query(\"SELECT * FROM large_table\")\n\n# ✅ Good: Lazy conversion, one row at a time (minimal GIL contention)\nfor row in result:\n    process(row)\n\n# ❌ Bad: Eager conversion, all rows at once (GIL bottleneck)\nall_rows = result.rows()  # or result.fetchall()\n```\n\nLazy iteration distributes GIL acquisition across rows, dramatically improving performance with multiple Python workers.\n\n## Examples \u0026 benchmarks\n\n- Examples: `examples/comprehensive_example.py`\n- Benchmarks: `benchmarks/`\n\n## Troubleshooting\n\n- Import/build: ensure Rust toolchain and `maturin` are installed if building from source\n- Connection: verify connection string; Windows auth not supported\n- Timeouts: increase pool size or tune `connection_timeout_secs`\n- Parameters: use `@P1, @P2, ...` and pass a list of values\n\n## Contributing\n\nContributions are welcome. Please open an issue or PR.\n\n## License\n\nFastMSSQL is licensed under MIT:\n\nSee the [LICENSE](LICENSE) file for details.\n\n## Third‑party attributions\n\nBuilt on excellent open source projects: Tiberius, PyO3, pyo3‑asyncio, bb8, tokio, serde, pytest, maturin, and more. See `licenses/NOTICE.txt` for the full list. The full texts of Apache‑2.0 and MIT are in `licenses/`.\n\n## Acknowledgments\n\nThanks to the maintainers of Tiberius, bb8, PyO3, Tokio, pytest, maturin, and the broader open source community.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frivendael%2Ffastmssql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frivendael%2Ffastmssql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frivendael%2Ffastmssql/lists"}