Torsemide infusion dose
torsemide continuous infusion dose protocol heart failure 2024
torsemide continuous infusion heart failure
Important note: Per the Michigan Medicine inpatient guidelines (2022), IV torsemide is no longer commercially available in the US as an IV formulation. Oral torsemide (with its high ~80% bioavailability) or IV furosemide is the practical alternative in most US settings.
| Clinical Scenario | Route | Torsemide Dose |
|---|---|---|
| Moderate overload | IV bolus | 10-20 mg |
| Severe overload | IV bolus | 20-100 mg |
| Severe overload | Continuous infusion | 5-20 mg/hr |
| Refractory to loop diuretics | Continuous infusion | 5-20 mg/hr (titrate) |
Create a quick reference PDF on loop diuretic dosing and conversions
ls -la /home/daytona/workspace/ 2>/dev/null && mkdir -p /home/daytona/workspace/loop-diuretic-ref
~/loop-diuretic-ref/build_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.colors import HexColor
from reportlab.platypus import PageBreak
# ── Colour palette ──────────────────────────────────────────────────────────
NAVY = HexColor("#1B3A5C")
TEAL = HexColor("#007C91")
LTBLUE = HexColor("#D6EAF8")
LTGREY = HexColor("#F4F6F7")
MIDGREY = HexColor("#BFC9CA")
WHITE = colors.white
BLACK = colors.black
RED = HexColor("#C0392B")
AMBER = HexColor("#D35400")
GREEN = HexColor("#1E8449")
HEADER_BG = NAVY
ROW_ALT = HexColor("#EAF4FB")
PAGE_W, PAGE_H = A4
MARGIN = 14*mm
doc = SimpleDocTemplate(
"/home/daytona/workspace/loop-diuretic-ref/loop_diuretic_quick_ref.pdf",
pagesize=A4,
leftMargin=MARGIN, rightMargin=MARGIN,
topMargin=18*mm, bottomMargin=14*mm,
title="Loop Diuretic Quick Reference",
author="Orris Medical Reference"
)
styles = getSampleStyleSheet()
# Custom styles
def S(name, **kw):
return ParagraphStyle(name, **kw)
TITLE = S("Title2", fontName="Helvetica-Bold", fontSize=20, textColor=WHITE, alignment=TA_CENTER, spaceAfter=2)
SUBT = S("Subt", fontName="Helvetica", fontSize=10, textColor=LTBLUE, alignment=TA_CENTER, spaceAfter=0)
SEC = S("Sec", fontName="Helvetica-Bold", fontSize=11, textColor=WHITE, alignment=TA_LEFT, spaceBefore=4, spaceAfter=2, leftIndent=4)
BODY = S("Body2", fontName="Helvetica", fontSize=8.5, textColor=BLACK, spaceAfter=2, leading=12)
BOLD = S("Bold2", fontName="Helvetica-Bold", fontSize=8.5, textColor=BLACK)
SMALL = S("Small", fontName="Helvetica", fontSize=7.5, textColor=HexColor("#555555"), spaceAfter=1)
TH = S("TH", fontName="Helvetica-Bold", fontSize=8, textColor=WHITE, alignment=TA_CENTER)
TD = S("TD", fontName="Helvetica", fontSize=8, textColor=BLACK, alignment=TA_CENTER, leading=11)
TDL = S("TDL", fontName="Helvetica", fontSize=8, textColor=BLACK, alignment=TA_LEFT, leading=11)
TDB = S("TDB", fontName="Helvetica-Bold", fontSize=8, textColor=BLACK, alignment=TA_CENTER, leading=11)
WARN = S("Warn", fontName="Helvetica-Bold", fontSize=8, textColor=RED, alignment=TA_LEFT)
NOTE = S("Note", fontName="Helvetica-Oblique",fontSize=7.5, textColor=HexColor("#2C3E50"), leading=11, spaceAfter=1)
def section_header(text):
tbl = Table([[Paragraph(text, SEC)]], colWidths=[PAGE_W - 2*MARGIN])
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), TEAL),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("ROUNDEDCORNERS", [3,3,3,3]),
]))
return tbl
def note_box(text, bg=HexColor("#FEF9E7"), border=AMBER):
tbl = Table([[Paragraph(text, NOTE)]], colWidths=[PAGE_W - 2*MARGIN])
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("BOX", (0,0), (-1,-1), 1, border),
]))
return tbl
def make_table(headers, rows, col_widths, alt=True):
header_row = [Paragraph(h, TH) for h in headers]
data = [header_row]
for i, row in enumerate(rows):
cells = []
for j, cell in enumerate(row):
if isinstance(cell, str):
style = TDL if j == 0 else TD
cells.append(Paragraph(cell, style))
else:
cells.append(cell)
data.append(cells)
style_cmds = [
("BACKGROUND", (0,0), (-1,0), NAVY),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, ROW_ALT] if alt else [WHITE]),
("GRID", (0,0), (-1,-1), 0.4, MIDGREY),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]
tbl = Table(data, colWidths=col_widths)
tbl.setStyle(TableStyle(style_cmds))
return tbl
# ── Document content ─────────────────────────────────────────────────────────
story = []
W = PAGE_W - 2*MARGIN
# ── TITLE BANNER ─────────────────────────────────────────────────────────────
title_tbl = Table([
[Paragraph("LOOP DIURETIC", TITLE)],
[Paragraph("Dosing & Conversion Quick Reference", SUBT)],
[Paragraph("For Acute Heart Failure & Volume Overload Management", SUBT)],
], colWidths=[W])
title_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("ROUNDEDCORNERS", [4,4,4,4]),
]))
story.append(title_tbl)
story.append(Spacer(1, 5*mm))
# ── SECTION 1: Drug Overview ──────────────────────────────────────────────────
story.append(section_header("1. LOOP DIURETIC AGENT OVERVIEW"))
story.append(Spacer(1, 2*mm))
overview_headers = ["Drug", "IV\nAvailability", "Oral\nBioavailability", "Onset\n(IV)", "Duration\nof Action", "Max Daily\nDose (oral)", "Notes"]
overview_rows = [
["Furosemide", "✓ Yes", "40–70%", "5–15 min", "6–8 h", "600 mg", "Standard first-line; variable absorption"],
["Torsemide", "Limited","~80–100%", "10–20 min", "12–16 h", "200 mg", "Preferred oral; IV form limited in US"],
["Bumetanide", "✓ Yes", ">80%", "5–15 min", "4–6 h", "10 mg", "40× potency of furosemide; CI: infusion myalgia"],
["Ethacrynic acid","✓ Yes", "Variable", "5–15 min", "6–8 h", "400 mg", "Use only if sulfa allergy; ototoxic"],
]
ow = [W*0.14, W*0.10, W*0.13, W*0.10, W*0.11, W*0.12, W*0.30]
story.append(make_table(overview_headers, overview_rows, ow))
story.append(Spacer(1, 3*mm))
# ── SECTION 2: Dose Equivalency ───────────────────────────────────────────────
story.append(section_header("2. DOSE EQUIVALENCY CONVERSIONS"))
story.append(Spacer(1, 2*mm))
eq_data = [
[Paragraph("Furosemide oral", TDL), Paragraph("<b>40 mg</b>", TDB), Paragraph("<b>80 mg</b>", TDB), Paragraph("<b>160 mg</b>", TDB), Paragraph("<b>240 mg</b>", TDB)],
[Paragraph("Furosemide IV", TDL), Paragraph("20 mg", TD), Paragraph("40 mg", TD), Paragraph("80 mg", TD), Paragraph("120 mg", TD)],
[Paragraph("Torsemide oral/IV", TDL), Paragraph("10–20 mg", TD), Paragraph("20–40 mg", TD), Paragraph("40–80 mg", TD), Paragraph("80–100 mg", TD)],
[Paragraph("Bumetanide oral/IV", TDL),Paragraph("1 mg", TD), Paragraph("2 mg", TD), Paragraph("4 mg", TD), Paragraph("6 mg", TD)],
]
eq_headers = ["Drug", "Reference\nDose", "2×", "4×", "6×"]
eq_col = [W*0.22, W*0.195, W*0.195, W*0.195, W*0.195]
header_row = [Paragraph(h, TH) for h in eq_headers]
eq_table_data = [header_row] + eq_data
eq_tbl = Table(eq_table_data, colWidths=eq_col)
eq_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), NAVY),
("BACKGROUND", (0,1), (0,1), HexColor("#D5F5E3")),
("BACKGROUND", (0,2), (0,2), LTBLUE),
("BACKGROUND", (0,3), (0,3), HexColor("#EBF5FB")),
("BACKGROUND", (0,4), (0,4), LTGREY),
("ROWBACKGROUNDS",(1,1), (-1,-1), [WHITE, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, MIDGREY),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("LINEABOVE", (0,1), (-1,1), 1.5, TEAL),
]))
story.append(eq_tbl)
story.append(Spacer(1, 2*mm))
story.append(note_box(
"Key rule: Furosemide 80 mg oral = Furosemide 40 mg IV = Torsemide 20 mg oral = Bumetanide 1 mg oral/IV\n"
"Oral torsemide dose = IV torsemide dose (no conversion needed due to ~100% bioavailability)\n"
"Switching furosemide oral → IV: halve the dose. Switching torsemide/bumetanide oral → IV: no dose change needed.",
bg=HexColor("#EAF7F0"), border=GREEN
))
story.append(Spacer(1, 3*mm))
# ── SECTION 3: IV Dosing by Severity ─────────────────────────────────────────
story.append(section_header("3. IV DOSING BY SEVERITY OF VOLUME OVERLOAD"))
story.append(Spacer(1, 2*mm))
sev_headers = ["Severity", "Drug", "IV Bolus Dose", "Continuous Infusion", "Monitoring"]
sev_rows = [
["Moderate", "Furosemide", "20–40 mg\n(or 1× oral dose)", "—", "UO, electrolytes, Cr"],
["", "Torsemide", "10–20 mg", "—", ""],
["", "Bumetanide", "0.5–1 mg", "—", ""],
["Severe", "Furosemide", "40–160 mg\n(2.5× oral dose)", "5–40 mg/hr", "Hourly UO, Na⁺, K⁺,\nCr, BP"],
["", "Torsemide", "20–100 mg", "5–20 mg/hr", ""],
["", "Bumetanide", "1–4 mg", "0.5–2 mg/hr\n(max 4 mg/hr)", "Caution: myalgias\nwith infusion"],
["Refractory", "Furosemide", "Up to 200 mg", "5–40 mg/hr ± escalate", "Add thiazide; monitor\nfor AKI"],
["", "Torsemide", "20–100 mg", "5–20 mg/hr", ""],
["", "+ Metolazone", "2.5–10 mg oral\n(30 min prior)", "—", "Profound electrolyte\nlosses possible"],
["", "+ Chlorothiazide","250–500 mg IV\n500–1000 mg oral", "—", "IV form faster onset"],
["", "+ HCTZ", "25–50 mg oral BD", "—", ""],
]
sw = [W*0.11, W*0.16, W*0.20, W*0.20, W*0.33]
sev_tbl_data = [[Paragraph(h, TH) for h in sev_headers]]
for row in sev_rows:
cells = []
for j, cell in enumerate(row):
if j == 0 and cell:
sty = S("SevBold", fontName="Helvetica-Bold", fontSize=8, textColor=NAVY, alignment=TA_CENTER)
cells.append(Paragraph(cell, sty))
elif j == 0:
cells.append(Paragraph("", TD))
elif j == 1 and "+" in cell:
cells.append(Paragraph(cell, S("Combo", fontName="Helvetica-Oblique", fontSize=7.5, textColor=AMBER, alignment=TA_LEFT, leading=10)))
else:
style = TDL if j in (1,4) else TD
cells.append(Paragraph(cell, style))
sev_tbl_data.append(cells)
sev_tbl = Table(sev_tbl_data, colWidths=sw)
sev_style = [
("BACKGROUND", (0,0), (-1,0), NAVY),
("GRID", (0,0), (-1,-1), 0.4, MIDGREY),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("SPAN", (0,1), (0,3)), # Moderate
("SPAN", (0,4), (0,6)), # Severe
("SPAN", (0,7), (0,11)), # Refractory
("BACKGROUND", (0,1), (-1,3), HexColor("#EBF5FB")),
("BACKGROUND", (0,4), (-1,6), HexColor("#D6EAF8")),
("BACKGROUND", (0,7), (-1,11), HexColor("#FDEBD0")),
("LINEABOVE", (0,4), (-1,4), 1.5, TEAL),
("LINEABOVE", (0,7), (-1,7), 1.5, AMBER),
("VALIGN", (0,1), (0,11), "MIDDLE"),
]
sev_tbl.setStyle(TableStyle(sev_style))
story.append(sev_tbl)
story.append(Spacer(1, 2*mm))
story.append(note_box(
"DOSE Trial (NEJM 2011, N=308): No significant difference between continuous infusion vs. IV bolus for symptom relief or renal function. "
"High-dose strategy (2.5× oral dose) yielded greater net fluid loss and dyspnea relief, with transient (reversible) creatinine rise.",
bg=LTBLUE, border=TEAL
))
story.append(Spacer(1, 3*mm))
# ── SECTION 4: Continuous Infusion Protocol ───────────────────────────────────
story.append(section_header("4. CONTINUOUS INFUSION PROTOCOL"))
story.append(Spacer(1, 2*mm))
inf_headers = ["Step", "Action", "Details"]
inf_rows = [
["1", "Loading bolus", "Give IV bolus first: Furosemide 40–80 mg or Torsemide 20–40 mg or Bumetanide 1–2 mg"],
["2", "Start infusion", "Furosemide: 5–10 mg/hr | Torsemide: 5 mg/hr | Bumetanide: 0.5 mg/hr"],
["3", "Assess at 1–2 hrs","Target UO ≥ 100–200 mL/hr. If inadequate, double the infusion rate"],
["4", "Titrate upward", "Furosemide: up to 40 mg/hr | Torsemide: up to 20 mg/hr | Bumetanide: up to 2 mg/hr (max 4 mg/hr)"],
["5", "Target fluid goal","Net negative balance: 1–2 L/day (acute HF); guided by clinical signs of congestion"],
["6", "Step down", "Once euvolemia achieved, transition to oral therapy using bioavailability conversion table"],
["7", "Monitor", "Serum Na⁺, K⁺, Mg²⁺, Cr, BUN q6–12h; BP, HR, urine output hourly during infusion"],
]
iw = [W*0.04, W*0.22, W*0.74]
story.append(make_table(inf_headers, inf_rows, iw))
story.append(Spacer(1, 3*mm))
# ── SECTION 5: Diuretic Resistance ───────────────────────────────────────────
story.append(section_header("5. DIURETIC RESISTANCE — CAUSES & MANAGEMENT"))
story.append(Spacer(1, 2*mm))
# Two-column layout
left_causes = [
[Paragraph("CAUSES OF RESISTANCE", S("CH", fontName="Helvetica-Bold", fontSize=8.5, textColor=TEAL))],
[Paragraph("• Reduced oral bioavailability (gut oedema)", BODY)],
[Paragraph("• Inadequate dose (below threshold)", BODY)],
[Paragraph("• Hypoalbuminaemia (reduced tubular delivery)", BODY)],
[Paragraph("• Neurohormonal activation (Na⁺ avid state)", BODY)],
[Paragraph("• Tubular adaptation (chronic use)", BODY)],
[Paragraph("• Concurrent NSAIDs (↓ renal prostaglandins)", BODY)],
[Paragraph("• Severe CKD (↓ tubular secretion)", BODY)],
[Paragraph("• Low cardiac output (↓ renal perfusion)", BODY)],
]
right_mgmt = [
[Paragraph("MANAGEMENT STRATEGIES", S("CH2", fontName="Helvetica-Bold", fontSize=8.5, textColor=TEAL))],
[Paragraph("• Switch oral → IV (bypass gut absorption)", BODY)],
[Paragraph("• Dose-escalate: 2.5× usual dose IV", BODY)],
[Paragraph("• Add distal tubule blocker (metolazone/HCTZ)", BODY)],
[Paragraph("• Consider torsemide or bumetanide (higher bioavail.)", BODY)],
[Paragraph("• Continuous infusion (sustained tubular levels)", BODY)],
[Paragraph("• Withhold NSAIDs", BODY)],
[Paragraph("• Correct hypoalbuminaemia if possible", BODY)],
[Paragraph("• Ultrafiltration if pharmacologic failure", BODY)],
]
left_tbl = Table(left_causes, colWidths=[(W/2) - 3*mm])
right_tbl = Table(right_mgmt, colWidths=[(W/2) - 3*mm])
for t in (left_tbl, right_tbl):
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), LTBLUE),
("BACKGROUND", (0,1), (-1,-1), LTGREY),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 6),
("BOX", (0,0), (-1,-1), 0.5, TEAL),
]))
two_col = Table([[left_tbl, right_tbl]], colWidths=[W/2, W/2])
two_col.setStyle(TableStyle([
("TOPPADDING", (0,0), (-1,-1), 0),
("BOTTOMPADDING", (0,0), (-1,-1), 0),
("LEFTPADDING", (0,0), (-1,-1), 0),
("RIGHTPADDING", (0,0), (-1,-1), 0),
("INNERGRID", (0,0), (-1,-1), 0, WHITE),
]))
story.append(two_col)
story.append(Spacer(1, 3*mm))
# ── SECTION 6: Special Populations ───────────────────────────────────────────
story.append(section_header("6. SPECIAL POPULATIONS"))
story.append(Spacer(1, 2*mm))
sp_headers = ["Population", "Consideration", "Preferred Agent / Adjustment"]
sp_rows = [
["CKD (eGFR < 30)", "Reduced tubular secretion; higher doses needed",
"Furosemide: may accumulate → ototoxicity risk at high doses\nTorsemide: preferred (less CKD accumulation)\nMay need 2–3× usual dose"],
["Hypoalbuminaemia\n(< 2 g/dL)", "Albumin binds loop diuretics for tubular secretion",
"Consider albumin 25 g IV + furosemide 40 mg IV combination\nEnhances delivery to tubular lumen"],
["Hepatic cirrhosis", "Gut oedema → poor oral absorption; secondary hyperaldosteronism",
"IV preferred; add spironolactone 100–400 mg/day\nTitre to weight loss 0.5–1 kg/day; monitor for encephalopathy"],
["Sulfa allergy", "Furosemide, torsemide, bumetanide are sulfonamide derivatives",
"Use ethacrynic acid (not a sulfonamide)\nNote: cross-reactivity with sulfa allergy is rare but documented"],
["Post-cardiac surgery", "High-dose vasopressors → renal vasoconstriction",
"Low-dose dopamine no longer recommended\nConsider furosemide infusion + thiazide if bolus-refractory"],
]
spw = [W*0.16, W*0.30, W*0.54]
story.append(make_table(sp_headers, sp_rows, spw))
story.append(Spacer(1, 3*mm))
# ── SECTION 7: Monitoring ─────────────────────────────────────────────────────
story.append(section_header("7. MONITORING PARAMETERS"))
story.append(Spacer(1, 2*mm))
mon_headers = ["Parameter", "Frequency", "Action Threshold / Target"]
mon_rows = [
["Urine output", "Hourly (infusion) / every 6–8 h (bolus)", "Target ≥ 0.5–1 mL/kg/hr; escalate dose if < 100 mL/2h"],
["Serum K⁺", "Every 6–12 h", "Replete if < 3.5 mEq/L; hold if > 5.5 mEq/L"],
["Serum Mg²⁺", "Daily", "Replete if < 0.8 mEq/L (concurrent hypoK⁺ often refractory without Mg²⁺ correction)"],
["Serum Na⁺", "Every 12–24 h", "Monitor for hyponatraemia; restrict free water if Na < 130"],
["Serum Cr / BUN", "Every 12–24 h", "Transient ↑ Cr acceptable if congestion improving; hold if ↑ > 0.5 mg/dL and no congestion"],
["Blood pressure", "Continuous / hourly", "Hold/reduce dose if SBP < 90 mmHg"],
["Body weight", "Daily (same time)", "Target loss 0.5–2 kg/day in ADHF; net fluid balance -1 to -2 L/day"],
["Hearing (ototoxicity)","With high doses", "Risk ↑ with rapid IV infusion, aminoglycosides, CKD; infuse furosemide ≤ 4 mg/min"],
]
mw = [W*0.18, W*0.20, W*0.62]
story.append(make_table(mon_headers, mon_rows, mw))
story.append(Spacer(1, 3*mm))
# ── FOOTER NOTE ──────────────────────────────────────────────────────────────
story.append(HRFlowable(width=W, thickness=1, color=MIDGREY))
story.append(Spacer(1, 1*mm))
footer_data = [[
Paragraph("Sources: Braunwald's Heart Disease (Table 49.6) · Harrison's Principles of Internal Medicine 22E · "
"Brenner & Rector's The Kidney · Fuster & Hurst's The Heart 15E · NKF Primer on Kidney Diseases 8E · "
"2022 AHA/ACC/HFSA HF Guidelines · DOSE Trial (NEJM 2011)", SMALL),
Paragraph("For clinical use with professional judgment.<br/>Not a substitute for institutional protocols.",
S("FR", fontName="Helvetica-Oblique", fontSize=7, textColor=HexColor("#888888"), alignment=TA_RIGHT))
]]
ft = Table(footer_data, colWidths=[W*0.72, W*0.28])
ft.setStyle(TableStyle([("VALIGN",(0,0),(-1,-1),"TOP"), ("LEFTPADDING",(0,0),(-1,-1),0), ("RIGHTPADDING",(0,0),(-1,-1),0)]))
story.append(ft)
# ── BUILD ─────────────────────────────────────────────────────────────────────
doc.build(story)
print("PDF built successfully.")
cd /home/daytona/workspace/loop-diuretic-ref && python build_pdf.py 2>&1
ls -lh /home/daytona/workspace/loop-diuretic-ref/
loop diuretic quick ref
PDF Document · PDF
Where is the pdf
loop diuretic quick ref
PDF Document · PDF
Create a dosing calculator or template for titrating loop diuretics
At what minimum level of Ph does all body enzymes work