01/07/2026

I LIKE it with ESCAPE

Most of you who are in TSQL world like me have used LIKE operator to find strings that not exactly match or find a row which contains a specific word.


For example, if you want to find names that starts with "ST", you would do someting like this in TSQL:

SELECT DisplayName FROM dbo.Users

WHERE DisplayName LIKE 'ST%'

This will bring display names like "Stephen", "Stanley", "Stone" etc.

But recently, I came across neat trick I can use with LIKE operator in TSQL, specially when using wild card charaters.

LIKE operator accept several wild card characters:

  • % matches any string of zero or more characters (this is the most used)
  • _ matches exactly one character
    • LIKE 'ST_' => matches => ST5, STT, ST3, etc (exactly one character after ST)
  • [...] matches any single character in a set or range (like [a-f])
    • LIKE 'ST[a-f]phen => matches => STaphen, STbphe, STcphen, STdphen, STephen, STfphen (characters from a to f)
  • [^...] matches any single character not in a set or range
    • Similar to above, but it is NOT match
When you using wild card characters like this, what if search string contains, wild card characters in it and you want to search fo them?

That is where ESCAPE hint comes handy.

For example let us consider following:

SELECT * FROM Products WHERE ProductCode LIKE '%_DISCONTINUED%';

In here we want to search for product codes, ended with "_DISCONTINUED" E.g. CAT1_DISCOUNTINUED, LOSS_DISCOUNTINUED. In other words we need "_" character (which LIKE operator consider as wild card character) in the search string.

In that scenario, we can change the T-SQL like below:

SELECT * FROM Products WHERE ProductCode LIKE '%\_DISCONTINUED%' ESCAPE '\';

This tells SQL parser, we are using "\" character as escape character and we escaping "_"character and telling LIKE operator to include it in the search.

If we don't use escape character, LIKE "%_DISCOUNTINUED%" will result in results like "ADISCOUNINUED", "IGNOREMEDISCOUNTINUED" which we really don't want.

Now \_ means "a literal underscore," and the query only matches rows where that underscore is actually there. The ESCAPE '\' clause is what tells SQL Server "hey, whenever you see a backslash in this pattern, treat the next character as literal, not special."

You don't always have to use ackslash, by the way — any single character works, as long as it's one you're not otherwise using in the pattern:

SELECT * FROM Products WHERE ProductCode LIKE '%!_DISCONTINUED%' ESCAPE '!';

Above T-SQL also brings same results.

Consider a example you want to find values like 50%.

SELECT * FROM Discounts WHERE Description LIKE '%50\%%' ESCAPE '\';

In above example you can see two % signs together, one sign tells SQL server next character appear need escaping from wild card treatment, there fore looking for 50%.

This setting is per query, andn will not effect all queries you execute after that.

Hope you have learned something new today like me.

Creating Videos for Tutorial using Remotion and Claude AI

I always believe, picture worth thousand words and video worth even more when it comes to do tutorials.

Recently I found a tool called Remotion.




Remotion is a short video generating app which uses React at the core. It is programmatic way to generate videos. Because it is programmatic, it works well with AI agents. This is why it has got my attention.

Therefore, in blog I'm going to show how remotion can be used with Claude.ai.

Since we are going to use Remotion with Claude.Ai, we need Claude code installed on the machine we are intended to use Remotion. Note that Claude code require paid subscription to work.

Another pre-requisite is Node.js. Install the latest Node.js (remotion will require v16 or higher).


Installation

Create a folder for your project and open that folder using terminal.

Type following:

npx create-video@latest

Follow the wizard in terminal.

Wizard will ask you to choose a template, choose the blank template as we ae just getting started and we intend to use this with Claude code.

Wizard will ask you to install TailWindCSS or not. For our beginner project, I would say no. But it is completely optional, choosing yes is also ok, but add more complexity.

Next question is "Add agent skills?". Definitely answer yes for this question.

You will be asked to choose which agent to get skills installed for. For us it is Claude code.

Then you will require to choose installation scope. I would keep it to project. You can choose Global if you prefer to install it once.

Installation method for skill is "Symlink"

Then wizard will install the skills and complete the installation.

Next step is to install all packages. To this run following:

npm i

Once all packages are installed, you can run the app using following command:

npm run dev

There will be nothing as we haven't add any frames.


Setting up Claude Code

Next step is to run Claude code on the projects folder.

Assuming you are still on the project folder in terminal type following to invoke Claude Code:

Claude

Assuming everything is setup correctly on Claude code, above will open Claude code in project folder.

run /init to initialize Claude code for the project. This will read the content of the folder and add the remotion skill and will create claude.md file for the project. Once this is done Claude is ready for your instructions.


Prompt

Now you provide the prompt to Claude code to build the video. More elaborate the prompt is more sophisticate your video will be.

To make this demo easier, I have asked following from Claude.ai (chat box) and create the prompt for me.

Create a prompt which I can give for Claude code to create simple video tutorial for SQL Server Constraint types using "Remotion". This is for remotion project. See remotion information on https://www.remotion.dev/ . SQL server Constraint video should be based on following blog post -> https://mpa-tech-tales.blogspot.com/2026/05/all-constraints-in-sql-server.html . It should have attractive opening screen and then will need several animating screens based on sections of the blog post. For example it should show a one animation screen explaining what are sql server constraints and then transit from that screen to next screen to show primary key constraints and related animations. Can you please generate the prompt for this?

It has created very comprehensive prompt, which I can paste or give Claude Code as a md file.

If the prompt is so big, it is advisable to instruct Code Claude to proceed phase by phase (after validating output of each phase). This will make sure Claude keep on the track we wanted instead of what it wanted.

Here is the first draft of the video created by Claude Code and remotion, using above prompt. It is not any mean polish video I wanted, but you can keep refine it with Claude Code to make it more preferable. 

In my opinion (as per now), Remotion + Claude can create you basic animation videos which you can use for tutorials or presentations. I think more appropriate use case is use it to create short animations which can be embedded/merge into your overall video, rather than making entire video from Remotion + Claude.

Schema Compare in SSMS 22.7.0

One of the coolest features released lately with SSMS (SQL Server Management Studio) is Schema Compare feature, which released on version 22.7.0.

To me it is one of anticipated feature. Yes, I know we had commercial products like Redgate SQL compare, but most organisations I worked with (small to mid size), doesn't have budget to afford that (or don't want to spend money on that).

There fore I had quick look at what it can do.

Currently it can be invoked through "Tools" menu in SSMS.


Worth noting, this feature is still in "Preview" mode, so it is not fully production ready and might not compare all of the database objects.

Schema Compare UI is as follows:


It has two main panes, one in top (showing what it compare) and one in bottom showing differences in objects when selected.

Optoins button give ability customize your comparison. When pressed following dialog box is opened:

Dialog box has two tabs.

  1. General Options
  2. Object types to compare

General options tab give you control over the comparison process and change script generation process. It gives options such as "Ignore ANSI NULL". Object Types to compare tab allows you to select which objects to compare:


You can compare following database types:
  • Databses
  • Databse Projects
  • Data-tier Application Files (dacpac)
As the source you can select any of these.


In my demo I have selected two versions of Stack Overlow database:


Then press "Compare" button.

Comparison takes little while, if you database has thousands of ojects, it will definitely take considerable time. I think this is something they need to focus on before release to production.

Here are the results from comparison:


It shows deleted table in target table -> dbo.LegacyPostVotes. New table in source database -> dbo.Badges. And also shows several changes. If you click on one of these lines, you can see detail view of the change. For example following screenshot shows, what appear when I select db.usp_GetUserById stored procedure, which was changed:


You can include/exclude changes you want or don't want. Then press either "Generate Script" button or "Apply" button. Generate Script button, generates the change script and open in a new Script Window. Apply button directly apply included changes into target database.

In my openion, It is not perfect, but start to walk write direction I would say.

I'm hoping to test this more with future releases and write about it.










25/05/2026

All Constraints in SQL Server

Last month we discussed quirky check constraint on SQL Server. That made me think of all constraints in SQL Server.



What is a constraints

Before we actually see all the constraint types in SQL Server, let us find out what is a constraint in SQL Server and why it is there.

Constraints are basically guard rails in database to prevent invalid, inconsistent and meaning data in tables. It is a rule SQL Server enforces automatically on a table column or set of columns.

Instead of trusting database users or applications, SQL server itself can enforce these rules to make sure data is protected.

Example for database rules are:

  • A person should not have two identical NIC (social security) numbers
  • An order should always belong to a customer
  • Age should never be negative

Constraints not only help to keep data in check, but it also help SQL Server Optimizer to arrive at better execution plans. For example, if optimizer knows data in a column cannot be null, it can create a plan which was otherwise not possible.


01. Primary Key Constraint

I think most important of all constraint is primary key constrint. Basic use of Primary key is identifying a specific row in a table. It is actually a combination of NOT NULL and UNIQUE constraints, which means you cannot have null on Primary Key columns and each value need to be unique. Otherwise SQL server cannot identify the row.

One table can have only one Primary Key constraint.

Primary key can be defined two ways. You can specify it as constraint on it's own line (like below).

CREATE TABLE Customers (

    CustomerId   INT           NOT NULL,

    Email        NVARCHAR(255) NOT NULL,

    FullName     NVARCHAR(255) NOT NULL,

    CONSTRAINT PK_Customers PRIMARY KEY (CustomerId)

);

or you can specify against the column. But in this case, you cannot specify a name for the constraint.

CREATE TABLE Customers (

    CustomerId   INT PRIMARY KEY,

    Email        NVARCHAR(255) NOT NULL,

    FullName     NVARCHAR(255) NOT NULL,

    CONSTRAINT PK_Customers PRIMARY KEY (CustomerId)

);

When you add a primary key to a table, that table is physically restructured to sort on specified primary key column values (default behaviour, but can be changed).

You can have composite primary keys. Which means you can define a primary key on more than one column.

CREATE TABLE Customers (

    Surname NVARCHAR(100)  NOT NULL,

    Email        NVARCHAR(255) NOT NULL,

    FullName     NVARCHAR(255) NOT NULL,

    CONSTRAINT PK_Customers PRIMARY KEY (Surname, Email)

);

Experts recommend to have primary key in every table.


02. Foreign Key Constraint

Foreign key constraint create relationship between two tables. This rule make sure, value user enter into the column actually exists in the foreign table.

For example, let us consider Order table.

CREATE TABLE Orders (

    OrderId    INT  NOT NULL,

    CustomerId INT  NOT NULL,

    OrderDate  DATE NOT NULL,

    CONSTRAINT PK_Orders PRIMARY KEY (OrderId),

    CONSTRAINT FK_Orders_Customers

        FOREIGN KEY (CustomerId)

        REFERENCES Customers (CustomerId)

);

In above example, CustomerId column in the Orders table reference (or have a relationship) with CustomerId field in Customers table. Which means, user cannot enter a customer id which doesn't exists in the Customers table into Orders table. This make sure orphan or invalid data is not entered into Orders table.

You can have self referencing Foreign keys. For example, see below Employees table:

CREATE TABLE Employees (

    EmployeeId INT           NOT NULL,

    FullName   NVARCHAR(255) NOT NULL,

    ManagerId  INT           NULL,  -- NULL means "this person has no manager" (the CEO, basically)

    CONSTRAINT PK_Employees PRIMARY KEY (EmployeeId),

    CONSTRAINT FK_Employees_Manager

        FOREIGN KEY (ManagerId)

        REFERENCES Employees (EmployeeId)  -- references the same table!

);

In here, "ManagerId" column has self-referencing relationship with EmployeeId column in same table. Basically, manager id is employee id of the manager of that particular employee.

As an additional feature, you can specify, what action to take when referenced column is updated or deleted.

CONSTRAINT FK_Orders_Customers

    FOREIGN KEY (CustomerId)

    REFERENCES Customers (CustomerId)

    ON DELETE CASCADE   -- delete the order if the customer is deleted

    ON UPDATE NO ACTION -- (default) block updates that would break the link

In above example if a customer is deleted in Custoemrs table, all orders reference by that customer id, will be also deleted.

It is recommend to use these actions carefully as it can create un-intended behaviours.

You can have foreign key constraint on multiple columns - Composit Foreign key. 

For example, consider following scenario:

CREATE TABLE OrderItems (

    OrderId   INT            NOT NULL,

    ProductId INT            NOT NULL,

    Quantity  INT            NOT NULL,

    UnitPrice DECIMAL(10, 2) NOT NULL,

    CONSTRAINT PK_OrderItems PRIMARY KEY (OrderId, ProductId),  -- composite PK

);


CREATE TABLE OrderItemNotes (

    NoteId    INT            NOT NULL,

    OrderId   INT            NOT NULL,

    ProductId INT            NOT NULL,

    Note      NVARCHAR(1000) NOT NULL,

    CONSTRAINT PK_OrderItemNotes PRIMARY KEY (NoteId),

    CONSTRAINT FK_OrderItemNotes_OrderItems

        FOREIGN KEY (OrderId, ProductId)               -- both columns together...

        REFERENCES OrderItems (OrderId, ProductId)     -- ...must exist as a pair

);

In above example, OrderId and ProductId is the primary key of the OrderItems tables. Then those two columns were referenced in OrderItemNotes table with a foreign key relationship. Important thing is combination need to be unique, therefore, you need Primary key or unique constraint on parent table on those columns you reference in child table.

However, note that two columns need to be in same table.

When referencing columns, child table doesn't have to have same name for the columns. But need to have compatible data types and need to match the order.


03. Unique Constraint

Keep all values in a column unique and no duplicates are allowed. For example, let us consider Email column in Customers table.

ALTER TABLE Customers

ADD CONSTRAINT UQ_Customers_Email UNIQUE (Email);

Above constraint make sure no two customers have same email address.

Unlike primary key, you can have multiple unique constraints defined on a table.

Unique key constraint considers NULL as a value and allow 1 null value (no duplicate nulls though). You cannot have filtered unique constraints; however, you can create unique index which makes the same functionality (we will not discuss about indexes here).

Like primary keys, you can have unique constraint on multiple columns. Which means uniqueness is checked across columns.

-- A customer can't place the same order twice on the same day

ALTER TABLE Orders

ADD CONSTRAINT UQ_Orders_CustomerDate UNIQUE (CustomerId, OrderDate);


04. Not NULL Constraint

Make sure column always have a value (no null values are allowed). This check is enforced every time row is inserted or updated.

CREATE TABLE Products (

    ProductId   INT            NOT NULL,

    ProductName NVARCHAR(255)  NOT NULL,  -- can never be empty

    Description NVARCHAR(MAX)  NULL,      -- optional

    Price       DECIMAL(10, 2) NOT NULL,

    CONSTRAINT PK_Products PRIMARY KEY (ProductId)

);

In above example, ProductName cannot be null, always need to have a value. But in contrast, Description can be null. Also note Primary key constraints automatically enforce not null.


05. Default Constraint

This constraint makes sure there is always a value in the specified column, even when user didn't insert a value.

CREATE TABLE Orders (

    OrderId    INT          NOT NULL,

    CustomerId INT          NOT NULL,

    OrderDate  DATE         NOT NULL,

    Status     NVARCHAR(50) NULL CONSTRAINT DF_Orders_Status DEFAULT 'Pending',

    CreatedAt  DATETIME2    NOT NULL CONSTRAINT DF_Orders_CreatedAt DEFAULT SYSDATETIME(),

    CONSTRAINT PK_Orders PRIMARY KEY (OrderId)

);

In above example, if user didn't specify a value to Status column, value "Pending" is get inserted. However, if user specify "NULL" value to Status field explicitly in the statement, NULL will be set for that column. Default value only applied when statement (insert or update) doesn't explicitly specify a value. To avoid this, you can have NOT NULL constraint on columns with default values.


06. Check Constraint

Check constraint allow you do define a custom rule using any expression that evaluate to true or false. If the expression evaluates to false for a given row, the insert or update will fail for that row.

ALTER TABLE Products

ADD CONSTRAINT CHK_Products_Price CHECK (Price > 0);

In above example, check constraint make sure, users cannot insert or update a row where Price is less than or equal to 0.

You can have check constraints on multiple columns:

-- A multi-column check: end date must be after start date

ALTER TABLE Promotions

ADD CONSTRAINT CHK_Promotions_DateRange

    CHECK (EndDate > StartDate);

However, if condition evaluate to NULL, then condition will pass the check. To avoid this you can pair the check constraint with NOT NULL.


Disabling Constraints

You can disable Foreign key constraints and Check constraints temporarily. This tick is used when loading data to a table fast (bulk load).

-- Disable a constraint

ALTER TABLE Orders NOCHECK CONSTRAINT FK_Orders_Customers;


-- Re-enable (and verify existing data)

ALTER TABLE Orders WITH CHECK CHECK CONSTRAINT FK_Orders_Customers;

Note that "WITH CHECK" tells SQL server to validate all existing rows. So if validation fails for any of the rows, constraints will not be enabled.

You can bypass this by specifying WITH NOCHECK, but this is not recommended.

If constraints are re-enabled with NOCHECK, they are marked as NOT TRUSTED. Which means those constraints will not be used in query optimization or in execution plan building (i.e. SQL server will not be believing data is valid).

01/05/2026

SQL Server Quirky Check Constraints

Recently at work, I found out curious table structure. I found out in one of the table, primary key had foreign key constraint. Well you will ask what's the strange thing about that? The strange thing is, this foreign key is referring to it self. To be clear, this is not a composite primary key, just a single column standard primary key. Investigation showed that it was done by mistake, no harm done, remove it and every one lived happily ever after.

But that got me thinking, why would SQL server allowed it? Does it has a use case? Curiously I went to find out about it more.

So code for this is something like below:

ALTER TABLE dbo.Employee WITH CHECK 

ADD CONSTRAINT FK_somename 

FOREIGN KEY (EmployeeId) REFERENCES dbo.Employee(EmployeeId)

So as would any one in this AI age would do, I have asked the question from 3 different AI models and all 3 basically gave the same answer.

As suspected, although valid syntax, this has no valid use case.

As a check constraint, this is utterly useless. Check constraint suppose to check value in foreign table already in source table. In this case of course value is already in source table because both are same and same column.

So will it fail when I insert a new value? No.

When inserting a brand new employee Id (e.g. 1010), value doesn't exists in the table yet. So FK constraint should fail. But it doesn't because order of operations happens in SQL server make sure it doesn't fail.

SQL Server's order of operations for an INSERT with FK constraints is roughly:

  • Write the row into the table (tentatively, within the transaction)
  • Then run the FK constraint check against the table's current state
  • If the check passes → commit. If not → rollback.
In step 2 new id is already in the table, even though it is not committed. There fore FK rule pass. There fore, no rollback.

Is it ok to leave it if I found such a quirk? No. It is no harm removing it. Plus it add although tiny, overhead to the insert operation. With thousands of insert these tiny overheads can add upto become issues. So remove it if you found a one.

Why does SQL Server allows it?
Well my geuess is not by design decission, probably by accident when designing all constraint rules.

If you find any useful use case for this, please let me know in comments.

This interesting nature of check contraints made me thinking, we should re-visit all SQL server constraints and see what they are (just for fun and education). I might try to write a blog on that next month.


24/04/2026

Schedule Tasks in Claude Cowork

It is all good to have AI agents helping you. But most annoying thing I see with them is I have to be there to invoke and guide. If there is a agent who activitate it self, it would be great. I know there are several solutions for this. But recently I came across Schedule Tasks in Claude Cowork. So I have given a try.

You need to have Claude desktop app installed on your desktop/laptop to get this working. I'm not going to go into installation of it and configuring it here, and assuming it is already done.

Accessing Schedule Tasks


Once you are in Claude desktop app, go to Claude Cowork tab and there you can see "Scheduled" section.

As per screenshot you see all your already created scheduled tasks. 

One of the most important thing to remember is these schedule tasks are NOT using Windows Task Scheduler or any windows service. Instead it purely depend on Claude App running on the desktop either open or in background. You can see if it is running background by checking apps on system tray. Every minute app check for schedule task list and see if it has a task to run and if it find a one it invoke it.


If Claude app is not running or computer is on sleep or computer is turned off, schedule task will not run on time. 

However, it will do a catch up next time you open up the Claude, if it missed a one. Note that it will only run one catch up. For example if computer was turned off for days, it will only run last missed run.

Scheduled task section has option to make sure computer doesn't go to sleep if claude app is running on background. If running the task on schedule is important, it will be good idea to turn this on.

Creating a Scheduled Task

Press the "New Task" button.

You will something like below:


Here I'm going to create claude cowork schedule task to grab latest tech info for my area of expertise to keep my self up to date.

Below the big box under the description, give proper instruction on what to do. Rather than typing your self you can use LLM chat to create a instructions for it. Here is what I have got as instructions:

31/03/2026

IP Ban Utility by Digital Ruby

Recently we commissioned a new CMS server for one of our client, although it mostly locked down, we noticed lot of failed login attempts in Windows Event Viewer.

If you go to Event Viewer -> Windows Logs > Security log and then filter for event id 4625 (Logon), you will be able to see login event (both success and failed). Audit failure events shows failed login attempts.


Relate to that 4740 (User Account Management) shows if above failed login attempts caused windows to lock down your account (in case hacker identified one of your account).


So how to prevent this. Most appropriate thing is to remove it from from public access. But server like CMS server need expose to internet. In that case you can lock down RDP and other access methods and just open web traffic. However, there are instances where servers need to be open for public traffic/access, specially if thirdparty is working on them (continuously).

In that case, you can restrict access to known IP addresses, or use VPNs.

If every method is un-available to you, I found out there is another option. That is banning IPs that un-authorized login attempts are coming. You can do this in your firewall.

But hardest thing is hackers change their IPs randomly, when you block one IP they come from another.

I found this elegant peice of software developed by Digital Ruby software house. It is called IP Ban. Process is simple. It monitor the event log for failed login attempts and if it exceed number you specified (from a particular IP), then it add a firewall rule to stop traffic from that IP address.

IPBan is available free on Github -> https://github.com/digitalruby/ipban

You can download it from here -> https://github.com/DigitalRuby/IPBan/releases

More information about developer can be found here -> https://www.digitalruby.com/server-software/

If you need pro version, this is the place to buy -> https://ipban.com/products

IPBan works on both Windows and Linux servers.

Installation is easy (run following in PowerShell):

$ProgressPreference = 'SilentlyContinue'; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; iex "& { $((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/DigitalRuby/IPBan/master/IPBanCore/Windows/Scripts/install_latest.ps1')) } -startupType 'delayed-auto'"

It is getting installed as Windows Service (IPBan). You can find the program in default insallation location "C:\Program Files\IPBan".

There is a xml config file on installation directory, where you can change many settings. But mostly default settings works. 

One of the interesting settings is "Whitelist" setting, which allows you to specify comma seperated list of IPs to avoid banning. Make sure to set this for one of your sever, so in case something goes wrong you can log on from there.

It adds Firewall rules prefixed with "IPBan_" so it is easy to identify. You can change the prefix if you prefer something else.

Usually ban is held for 1 day, but you can change this setting.




21/03/2026

SQL Server SESSION_CONTEXT

Last week I came across intresting challenge. I was enhancing an auditing framework for application. This application used SQL triggers for auditing. Basically all tables in database (excluding some system table), had auditing fields such as created date, created by, last modified date and last modified by. Each table where it wanted to audit, had triggers to write values of those field everytime row is updated. Audited data was written to big audit log table. Basically everytime row is updated (or created) above audit fields were updated by app, then trigger write the values of those auditting fields to audit log. But issue was, how to track who deleted a row?

When you delete a row, application cannot write to those auditing fields. I mean you can write, but that will be just stupid to update each row just before it get deleted. That will increase writes just to make it auditable (plus extra audits). So I had to find a solution.

My research showed one of the ways to tackle is SQL Server Session Context.



It is a simple concept introduced in SQL Server 2016. Session context is array of key-value pairs attached to a session.

So in your session, you can specify session specific meta data in this array and read it from SQL server to make different dicissions based on the meta data specified for connection. It is like dictionary attached to your connection.

Session context is stored on memory, therefore, it is fast. It is scoped for session and therefore, isolated from others.

So how to make it work?

First you need to set the values in the context:

EXEC sp_set_session_context 

    @key = N'UserId', 

    @value = 123;

Then you can use those values through out your session:

SELECT SESSION_CONTEXT(N'UserId');

If you don't want to make it updatable, you can set the read-only flag:

EXEC sp_set_session_context 

    @key = N'UserId', 

    @value = 123,

    @read_only = 1;


So how did it help my situation:

Well, just before the delete, I could set the "UserId" or "OperatingUserId" like variable in the session context. Then on the trigger, I can read this value and create the audit log for delete with correct user id.

You will say 'Well, it is still a additional write, just before delete?'. 

Yes and No. It is a update to connection, which is held in small part of the memory, so it is not going to write to disk. In fact there is a limitation on session context. Session context only allow maximum 256 key-value pairs, but total size need to be under 1MB (approx).

But be aware it is not a place to hold password like secret information, because if multiple people share the connection (like through application), can see the whole context.

In a connection, where session is shared (like through multi user application). It is vital that you set the userId like values just before where it is going to be use. Otherwise you will be using wrong values, because other users may also set it. There might be concurrency issue, but in my case, rows are deleted in-frequently, so it was ok.

In addition to auditing, you can use it to identify tenant when you application is multi tenant. And it can also be used with row level security (cuatiosly).

Don't over use it, just use it sparegly, 

There are know issues, where session context provide wrong results when queries go parallel. But in my case, delete is always single threaded.



18/03/2026

Agent Types in VS Codes

Recently I was working on VS code lot. In fact I was working with Github Copilot lot on VS Code. However have to admit I'm not aware of full capabilities of agentic framework available on VS Code through Github Copilot. I'm just learning as I go.

One of the options you see on Github Copilot window is Agent Type.


There are few options available in this:

  • Local
  • Background
  • Cloud
  • Claude (thirdparty)

I wanted to find out what are the different capabilities of each of the Agent types. Here is my find.

Local

Of course this is the default agent which I'm using most of the time. In fact all the time so far. 

Local agent runs within your VS code environment in your local machine. There fore it has access to all the resouces in VS Code, such as your workspace, files, context (stack trace, unit test results, liniting errors, etc.). 

It can use all models available in VS code. Also have access to all agent tools (browsing, MCP and extension provided tools).

Mostly, it is interactive, you can chat with it and give real time feedback and you can steer them the direction you want easily if you see them going off track.

That's why local agents are the ones I use most.

Background

Background agent, also known as Copilot CLI sessions, run in background. Main feature of this is they run even you close down VSCode. These are well suited for long running tasks, such as you have defined and planned all the steps need to take and where you can sure agent can run independantly long time without your input.

When these sessions require attention, they will notify in chat window same way the local agent would do.

There are two isolation levels for these:

  • Worktree -> create seperate GIT work tree and work independantly to your main code.
  • Workspace -> workspace is where background agent also works in same environment as what you see in VSCode
There are some limitations with background agents. They cannot access all tools in VSCode, plus they don't have access to extension provided tools. Also they are limited to CLI provided models.

Background agent can be start using agent type drop down:


Then you can selection isolation in isolation drop down:


You can also specify a working folder, so agent can independantly work without interfearance:



Cloud Agent

Cloud agents as name suggest runs on cloud (or remote infrastructure). The main cloud agent is Github Copilot cloud agent, which runs on Githug infrastructure (i.e. your remote github repository).

Github Copilot cloud agent as integrated access to Git hub repositories, there for it can do most of the actions (if not all) that any github user can do. Those include large scale refactoring, complete feature development, automatic pull request creation and code reviews.

You can also have thirdparty cloud agents, such as Claude Code and Open AI's Codex.

You can select cloud agent from agent type drop down:



Then you can select repository and give instruction to the agent.

24/02/2026

BMAD Method - Part 2

Since I last talk about BMAD Method (here), about 2 months ago. It has evolved fast. Infact, today (23/02/2206) they have released their newest stable release for version 6. If you can remember, I used version 4.4x in my last article. That's how fast AI industry is moving.

Since then I have used BMAD method successfully in one of production application, and I'm very happy about it.

Since I bought Claude pro subscription recently, I'm going discuss how we can use BMAD method through Claude code (which is the recomended way of using it by its developers).

You can use ClaudeCode, in any terminal (standalone terminal, terminal in a IDE or any other terminal supported way). But since I'm familiar with VSCode, I'm going to use terminal in VSCode to use ClaudeCode.

First thing I would suggest doing in install ClaudeCode extension into VSCode.


Once extension is installed, you can go through onboarding wizard to get it configured. There are several ways you can use ClaudeAI models through ClaudeCode. 

Since I have pro subscription, I will use that. Note that using throug API is very costly. When you click on above button, it will link to your subscription.

Now ClaudeCode extention is configured. Let's get started... well not so fast. ClaudeCode actual program is still not installed in your computer (just the VS Extension is installed). You need to install it using PowerShell.

Here is the command for that (runs on powershell)

irm https://claude.ai/install.ps1 | iex

Or you can download the installation from Antropic.

It take little bit time based on your internet speed to install ClaudeCode through powershell, so be patient. Once installed you need to add installation path to the "Path" environment variable for easy access.


Once ClaudeCode is configured, you can launch it through VSCode. There will be a Claude icon on top right hand corner in VSCode window.

Now that we have both installed and cofigure, open a terminal and let's go to the folder where we want to create the app (or where existing app is).

Then install bmad method with npx:

npx bmad-method install

Since you specify the version, it will ask to install the latest stable version:


Installation wizard starts and following screen appear. At the end of that screen it will ask directory to work.


You can accpet the current directory or give folder path to create a new. If it doesn't exists bmad will ask your permission to create it.

I have chosen bmad6test folder.

Then on next screen you need to select modules. BMAD is a platform where you have core framework and you can add modules according to your requirement. For example, if you developing a Game, you can install "BMad Game Dev Studio" module.


I have chosen BMad Agile-AI Driven Development module.

You can choose to install custom modules, but that for advanced users.

Then the most important decision, you will require to choose which AI tool you will be using BMAD method with.


As you can see Claude Code and Cursor is the preferred ones. But there are long list you can choose from including previously shown Github Copilot.

Next it will ask what should it call you (a name for your self).

Next it will ask, preferred language and output language, where output document should be saved and ect.

Module installation can be done express way or customized approach, but I choose express way and use all defaults (which suites me, but if you prefer you can test with custom approach).

That's it.

After BMAD installation, lets switch to the working directory and start VSCode.

Once you inside VSCode open ClaudeCode.


In the ClaudeCode prompt, you can start typing bmad commands and it will show what is available.


Good place to start is bmad-help method.





01/02/2026

Google Antigravity

These days every one in developer world is talking about Google's Antigravity. So I was also curious  to find about it.



So what is Google's Antigravity? Well, it is Integrated Development Environment (i.e. IDE), similar to popular IDEs like cursor, windsurf and VSCode. Like all of above mentioned, it is a fork of VSCode.

So what is the uniqueness of that? Well, that's what I want to find out too. As per Google, it is not only an IDE, it is an agent management system. In order to find out about more, I decided to install and test.

You can download Google's Antigravity from this site. Available for Mac, Windows and some Linux distributions (e.g. Ubantu 20+). Windows installation is about 152 MB.

Setup starts with usual User Agreement screen:


Then you get to choose the installation location. You will require about 800 MB disk space for this. Next screen allows you to select additional tasks.


Installation is relatively quick (will depend on your computer/disk speed, took only 2min on mine).

Once installed, unlike VSCode, you are taken through setup wizard.


You can import your setting from other similar IDEs. But I choose to start fresh as I didn't want to effect all the testings I have done with other IDEs.

In next step you can select the theme (light, dark, solarized light, tokyo night). I choose dark of course.

Next step is vital. You get to choose how autonomus your agents will be within IDE.


Since this is local installation, agent get access can access all resource in your system, something you might not want to happen. There fore you can select how much freedom you are given to agents. You have 4 options:

  • Secure mode is the safest, in this more agent will ask permission for everything before it go and do something.
  • Review driven development (whic is the recomended), require you to review what agent is going to do before it does.
  • Agent-driven development -> Give more freedome to agent to do most tasks.
  • Custom configuraiton allows you to configure which tasks are allowed and which are not allowed.
In next step you configure your editor.


In order to use Antigravity for free, you need google and gmail account. Wizard will ask you to sign in to this account in next screen.


Final screen is on terms of use.

This is what opening screen looks like:



It is some what similar to VSCode. Note the "Agent Manager" button in the second row in middle. I think is the uniqueness of the IDE.

I will have a play and let you know how my experience is in future blogs.

I LIKE it with ESCAPE

Most of you who are in TSQL world like me have used LIKE operator to find strings that not exactly match or find a row which contains a spec...