Feyn AI Releases SQRL, a Family of Text-to-SQL Models That Tests the Database Before Writing a Query

Most text-to-SQL systems treat the function as a translation. Feyn AI (a YC-backed startup) reframes it when it's tested. Feyn's team released SQRL, a family of models that turn natural language queries into SQL. Instead of generating a query on the fly, SQRL can scan the database first. This allows it to resolve ambiguity and only write queries that are supported by the data.
The Feyn team reports that the flagship SQRL-35B-A3B is reaching 70.6% implementation accuracy in BIRD Dev. That figure beats Claude Opus 4.6 at 68.77% under the same test. Three test sites are open to Hugging Face: SQRL-4B, SQRL-9B, and SQRL-35B-A3B.
A query can be valid SQL and have an error
Text-to-SQL is often described as an interpretation problem, but that framework misses the most difficult part. A query can be a valid SQL query and return a negative response. It can join wrong tables, read an obscure column, or filter missing values. None of these errors are infallible, so none are caught by execution alone.
Schema information does not prevent them. A schema shows tables, columns, types, and sometimes relationships. It does not indicate that the region is saved as Alameda, Alameda Countyor ALAMEDA. It won't tell you which joins produce duplicate rows.
The BIRD benchmark makes this failure measurable. Its databases take real domains and contain incomplete values, ambiguous columns, and trivial relationships. The system is detected by executing its SQL and comparing the returned rows with the reference result. In query languages, syntactic correctness is not enough. Feyn's key insight is that missing information already resides within the database. The model requires permission to request it.
SQRL checks before it responds
SQRL finds the query, its schema, and optional evidence about the database. If that context is sufficient, it returns the query at once. If something remains unclear, it uses read-only queries and uses the returned rows to write its final answer. The decision to evaluate is the constraints. Counting rows in a single table doesn't need to be checked, so SQRL responds directly.
Communication uses two different actions. An the block request is checked in the database. An block commits to the last question. The harness uses test queries in read-only mode and returns its rows internally tags. SQRL can test up to five times, although most queries finish in a few steps.
The explainer below walks through both behaviors in real examples, then compares the family and boundary models in BIRD Dev.
' + s.label +'
' +'
' + s.desc +'
' +'
' + s.code + '
'; trace.appendChild(div); setTimeout(function(){ div.classList.add('show'); resize(); }, 350 * (idx+1)); }); setTimeout(function(){ runbtn.disabled = false; runbtn.textContent=”Replay”; resize(); }, 350 * (ex.steps.length + 1)); } document.getElementById('runbtn').addEventListener('click', run); // —- tabs —- Array.prototype.forEach.call(root.querySelectorAll('.tab'), function
{ name:”SQRL-35B-A3B”, val:70.60, sqrl:true },
{ name:”SQRL-9B”, val:69.80, sqrl:true },
{ name:”SQRL-4B”, val:68.80, sqrl:true },
{ name:”Claude Opus 4.6″, val:68.77, sqrl:false },
{ name:”Claude 4.5 Sonnet”, val:67.34, sqrl:false },
{ name:”Qwen3-Coder-480B-A35B”, val:66.17, sqrl:false },
{ name:”GLM-4.7″, val:63.82, sqrl:false },
{ name:”DeepSeek-R1″, val:61.67, sqrl:false },
{ name:”Kimi-K2-Thinking”, val:60.63, sqrl:false }
]; var chartDrawn = false; function drawChart(){ var chart = document.getElementById('chart'); chart.innerHTML = ''; bench.forEach(function(b){ var row = document.createElement('div'); row.className=”bar-row”; row.innerHTML = '
' + b.name +'
' +'
'; chart.appendChild(row); }); // animate the width (scale: 0-100 maps to full track) setTimeout(function(){ Array.prototype.forEach.call(chart.querySelectorAll('.bar-fill'), function(f, i){ f.style.width = bench[i].val + '%'; }); setTimeout(resize, 1100); }, 60); chartDrawn = true; } // —- resize automatically (height of component itself + 40, per house rule) —- function resize(){ try { var h = root.offsetHeight + 40; parent.postMessage({ type:'sqrl-resize', length: h }, '*'); } catch(e){} } window.addEventListener('load', function(){ render(); resize(); }); window.addEventListener('resize', resize); setTimeout(resize, 300); })();



